我有以下代码:
omp_set_num_threads(10);
int N = 10000;
int chunk = 1000;
int i;
float a[N];
for (i=0; i < N; i++)
{
a[i] = i;
}
#pragma omp parallel private(i)
{
#pragma omp for schedule(dynamic,chunk) nowait
for (i=0; i < N; i++) a[i] = a[i] + a[i];
}
顺序代码是相同的,没有两个pragma指令。
顺序〜150us 平行〜1100us
这是一个巨大的差距,我希望情况会相反。
有人知道哪里出了问题吗,还是OpenMP在后台有太多事情要做? 有人举一个例子,我可以看到并行化的for循环更快吗?
谢谢
答案 0 :(得分:2)
启动10个线程并进行管理要比添加10,000个元素昂贵。如果您使用的真实内核少于10个,则它们将争夺时间片,并导致上下文切换和(可能)更多的缓存未命中。并且您选择了动态调度,这意味着需要进行一些同步以帮助线程确定它们将要执行的块(不是很多,但是当分配的工作相对而言微不足道时,足以减慢速度)
在一个轶事launching a no-op thread and immediately detaching it cost about 10 μs中,这些线程不需要执行任何操作。在您的情况下,仅用于启动线程就需要100μs,而忽略了线程引入的所有其他低效率问题。
并行化有助于处理较大的工作量,或者当工作人员多次用于许多中等大小的任务时(因此启动线程的成本只是其工作量的一小部分)。但是,执行10,000次加法运算对于CPU来说是一个巨大的改变。您只是做得还不够,无法从并行化中受益。