c++ - 为什么 OpenMP 比顺序执行慢?
问题描述
我有以下代码:
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 循环更快吗?
谢谢
解决方案
启动十个线程并管理它们比添加 10,000 个元素更昂贵。如果您在一个真正核心少于 10 个的系统上,它们将竞争时间片,并导致上下文切换和(可能)更多的缓存未命中。而且您选择了动态调度,这意味着需要进行一些同步来帮助线程确定它们将要执行哪些块(不是很多,但在分配的工作相比之下相当微不足道时足以减慢速度) .
在一个轶事中,启动一个无操作线程并立即将其分离大约需要 10 μs,而这些线程不需要做任何事情。在您的情况下,这只是启动线程的 100 μs,忽略线程可能引入的所有其他低效率。
并行化有助于大型工作负载,或者当工作人员多次用于许多中等规模的任务时(因此启动线程的成本只是他们所做工作的一小部分)。但是执行 10,000 次加法对 CPU 来说是小菜一碟。您只是做得还不够,无法从并行化中受益。
推荐阅读
- vue.js - 如何从 vue 应用程序生成包含所有节点模块的包?
- javascript - 删除然后添加子节点
- doctrine-orm - 如何使用 Doctrine DBAL、TYPO3 和 TypoScript 进行随机排序
- c++ - CPP Prime Generator SPOJ 筛
- nginx - nginx 没有显示带有 uwsgi 的自定义错误页面
- r - while (tol > 1e-05) { 中的错误:R 中代码牛顿法中的缺失值
- javascript - JavaScript 函数不会触发 CSS 更新和 .getElementById
- r - 如何通过逐渐增加的数据顺序组合来改变新列?
- c - 0x53918F0E (ucrtbased.dll) 处未处理的异常
- objective-c - 如何将 Void -> Void 闭包附加到 Objective-C 中的头文件