【发布时间】:2019-05-27 17:48:45
【问题描述】:
我注意到为某些代码运行多个线程比运行一个线程要慢得多,我真的很想知道为什么,有人可以帮忙吗?
代码说明: 有时,我有一个非常大的数组,我需要以并行方式处理其中的一部分以进行优化,一行的每个“部分”都会在特定线程中循环和处理,现在我注意到如果我只有一个“部分”,即整个数组和一个贯穿它的工作线程比我划分数组并将其作为具有不同线程的单独子数组处理要快得多。
bool m_generate_row_worker(ull t_row_start,ull t_row_end)
{
for(;t_row_start<t_row_end;t_row_start++)
{
m_current_row[t_row_start]=m_singularity_checker(m_previous_row[t_row_start],m_shared_random_row[t_row_start]);
}
return true;
}
...
//code
...
for(unsigned short thread_indx=0;thread_indx<noThreads-1;thread_indx++)
{
m_threads_array[thread_indx]=std::thread(
m_generate_row_worker,this,
thread_indx*(m_parts_per_thread),(thread_indx+1)*(m_parts_per_thread));
}
m_threads_array[noThreads-1]=std::thread(m_generate_row_worker,this,
(noThreads-1)*(m_parts_per_thread),std::max((noThreads)*(m_parts_per_thread),m_blocks_per_row));
//join
for(unsigned short thread_indx=0;thread_indx<noThreads;thread_indx++)
{
m_threads_array[thread_indx].join();
}
//EDIT
inline ull m_singularity_checker(ull t_to_be_ckecked_with,ull
t_to_be_ckecked)
{
return (t_to_be_ckecked & (t_to_be_ckecked_with<<1)
& (t_to_be_ckecked_with>>1) ) | (t_to_be_ckecked_with &
t_to_be_ckecked);
}
【问题讨论】:
-
如果线程不相互干扰(任务完全独立),则检查实际工作负载是否明显大于启动线程的开销。不清楚你到底在做什么,所以很难说到底是什么问题。
-
出现这种情况的原因有很多。一些更通用的包括凝视比您的硬件更多的线程,或者
m_signularity_checker做一些只能按顺序运行的事情(比如分配内存或受互斥体保护的部分)。如果没有更多代码显示您正在尝试的内容,我们无法判断您的具体问题是什么。 -
“为什么在某些特定情况下拥有多个线程(并行处理)会降低性能?” - 很多很多的原因。有些是; 1)创建和销毁线程的开销超过了每个线程中并行完成的工作量。 2)线程需要大量同步并有效地串行运行,因此线程只会增加开销。 3) 错误共享> 和线程严重影响性能时的类似问题。 4)使用比可用硬件线程更多的活动软件线程过度使用系统会导致执行上下文切换的大量开销。 5) 很多,很多更多。
-
另一个可能的原因是测量不正确。
-
我编辑了帖子以包含缺少的功能@FrançoisAndrieux 我认为你可能是对的,你知道如何优雅地测量/确保这一点(分别测量处理和上下文切换时间)?
标签: c++ multithreading