我想优化我的顺序代码,以形成一个梯度。
主线程计算图像边界的梯度,其他线程计算图像块的梯度,使用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();
}
}发布于 2017-02-20 13:35:51
对于任何并行执行,您都必须考虑到Amdahl定律。它指出,并行执行某些任务所需的时间与处理器数量不成线性关系:
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%运行速度最高为p=50%的两倍)。
此外,您还必须考虑到,在现实中添加更多的并行性也会增加更多的开销(用于同步、设置线程等),因此更实际的估计是:
t = ( (1-p) + p/n ) * T + o*p
^^ overhead这个t作为处理器数量的函数,对于一定数量的处理器,p有一个最小值。向问题中添加更多的处理器并不会导致加速,而是会导致速度减慢,因为您需要完成p部分的最小时间为零,但是通过添加更多的处理器所增加的开销是无限的。
这并不能解释为什么在您的情况下没有加速,但一般来说,简单地在任务上添加更多的处理器并不总是导致加速,这并不是什么大意外。
发布于 2017-02-20 13:22:11
对于容易拆分的任务来说,并行执行是一个巨大的好处,线程将不依赖于自己,但是创建线程是有代价的。假设一台计算机只运行您的程序(没有操作系统,也没有其他进程)。处理器有两个核,它们本身就是处理器,可以并发运行任何代码。在只有一个线程的情况下,第二个核心处于绝对无所作为的状态,因此有可能加快速度。如果您生成第二个线程(并给它任务的50% ),那么第二个核心现在也能工作,理论上来说,加速比是2(忽略顺序部分和实际方面)。现在,让我们创建4个线程。等等..。我们有两个处理器和四个线程?是的,现在每个CPU做了不止一件事情,在改变它工作的任务之前,CPU必须切换上下文(改变寄存器的值以保存适当的变量值,转到不同的代码部分等等),这需要时间,如果创建过多的线程,实际上需要花费更多的时间来完成工作。这可能会对任何线程应用程序产生巨大影响,在决定要运行多少线程之前,应该注意到这一点。
请注意,这篇文章简化了许多现代CPU的运行效率超过了每个内核一个线程(即。HyperThreading)。
发布于 2017-02-20 13:12:31
好像你的CPU是双核的。因此,实际上,只有两个任务可以并行执行。
https://stackoverflow.com/questions/42345410
复制相似问题