为什么使用超过2个线程会消耗更多时间?

时间:2017-02-20 13:06:54

标签: c++ multithreading

我想优化我的顺序代码以制作渐变。

主线程计算图像边界的渐变和其他线程,每个线程计算图像块的渐变, 使用2个线程和主线程给出的结果比顺序代码更好但使用超过2个线程,但它消耗更多时间并且看起来比顺序更差。

我尝试使用此代码来加快渐变过程:

 for (int n = 0; n<iter_outer; n++)
        {
            int chunk = 1 + ((row - 1) / num_threads); //ceiling
            int start=0;
            int end=0;
            //Launch a group of threads
            for (int tid = 0; tid < num_threads; ++tid)
            {
                start = tid * chunk;
                end = start + chunk;
                t[tid] = thread(gradient, tid, g, vx, vy, row, col, 1, start, end);

            }
            //Launched from the main;
            gradient(1, g, vx, vy, row, col,0, start, end);
            //Join the threads with the main thread
            for (int i = 0; i < num_threads; ++i)
            {
                t[i].join();

            }

        }

3 个答案:

答案 0 :(得分:4)

For any parallel execution you have to take into account Amdahl's law中保存价值。它指出并行执行某项任务所需的时间与处理器数量不成线性关系:

t = ( (1-p) + p/n ) * T

其中

T is the time needed for the task when it is done sequentially
p fraction of time that can be parallelized
n is the number of processors

请注意,我使用了稍微不同的公式,但声明是相同的:您获得的总加速时间受1/(1-p)的限制(例如,如果p=50%您的并行版本最快运行速度的两倍) 。

除此之外,您还必须考虑在实际中添加更多并行性还会增加更多开销(用于同步,设置线程等),因此更实际的估算是:

t = ( (1-p) + p/n ) * T  + o*p
                           ^^ overhead

t作为处理器数量p的函数,对于特定数量的处理器具有最小值。为问题添加更多处理器不会导致加速,而是导致速度减慢,因为您需要执行p部分所需的最短时间为零,但通过添加更多处理器而增加的开销会增加。

这并不能解释为什么你不能在你的情况下获得加速,但总的来说,在任务上添加更多处理器并不总是会导致加速并不是一个大惊喜。

答案 1 :(得分:-1)

并行执行对于易于拆分且线程不依赖于自身的任务来说是一个巨大的好处,但是创建线程确实需要付出代价。让我们想象一下,除了运行程序之外,计算机不会做任何事情(没有操作系统,也没有其他进程)。处理器有2个内核,它们本身就是处理器,可以同时运行任何代码。如果只有一个线程,则第二个核心位于绝对没有的位置,因此有可能加速。如果你产生第二个线程(并给它50%的任务),第二个核心现在也可以工作,理论上加速是2(忽略顺序部分和实际方面)。现在,让我们制作4个帖子。等等......我们有两个处理器和4个线程?是的,现在每个CPU都做了不止一件事,在更改它工作的任务之前,CPU必须切换上下文(更改寄存器的值以保存适当的变量值,转到不同的代码部分等等)这需要时间和如果你创建了太多的线程,它实际上比完成工作需要更多的时间。这可能对任何线程应用程序产生巨大影响,在决定运行多少线程之前应该注意。

请注意,这篇文章简化了许多现代CPU可以高效运行每个核心一个线程(即超线程)。

答案 2 :(得分:-7)

看起来你的CPU是双核的。所以,实际上,只有2个任务可以并行完成