- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我运行了一个 OpenMP 程序来执行 Jacobi 方法,它运行良好,2 个线程的执行速度略高于 1 个线程的 2 倍,4 个线程的执行速度比 1 个线程快 2 倍。我觉得一切都在完美地工作……直到我正好达到 20、22 和 24 个线程。我一直在分解它,直到我有了这个简单的程序
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[]) {
int i, n, maxiter, threads, nsquared, execs = 0;
double begin, end;
if (argc != 4) {
printf("4 args\n");
return 1;
}
n = atoi(argv[1]);
threads = atoi(argv[2]);
maxiter = atoi(argv[3]);
omp_set_num_threads(threads);
nsquared = n * n;
begin = omp_get_wtime();
while (execs < maxiter) {
#pragma omp parallel for
for (i = 0; i < nsquared; i++) {
//do nothing
}
execs++;
}
end = omp_get_wtime();
printf("%f seconds\n", end - begin);
return 0;
}
这里是不同线程数的一些输出:
./a.out 500 1 1000
0.6765799 seconds
./a.out 500 8 1000
0.0851808 seconds
./a.out 500 20 1000
19.5467 seconds
./a.out 500 22 1000
21.2296 seconds
./a.out 500 24 1000
20.1268 seconds
./a.out 500 26 1000
0.1363 seconds
如果 20 之后的所有线程都继续这样,我会理解一个很大的减速,因为我认为这将是线程开销(尽管我觉得这有点极端)。但即使改变 n 也会使 20、22 和 24 的时间保持不变。将 maxiter 更改为 100 确实会将其缩小到大约 1.9 秒、2.2 秒......,这意味着线程创建本身导致了速度减慢,而不是内部迭代。
这是否与操作系统试图创建它没有的线程有关?如果它意味着什么,omp_get_num_procs()
返回 24,它在 Intel Xeon 处理器上(所以 24 包括超线程?)
感谢您的帮助。
最佳答案
我怀疑问题是由于一个线程在一个核心上以 100% 的速度运行。由于超线程,这实际上消耗了两个线程。您需要找到导致此问题的核心并尝试排除它。假设它是线程 20 和 21(你说它在你的问题中从 20 开始 - 你确定吗?)。尝试这样的事情
GOMP_CPU_AFFINITY = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 22 23
我以前从未使用过它,所以您可能需要仔细阅读一下才能正确使用。 OpenMP and CPU affinity您可能需要先列出偶数线程,然后再列出奇数线程(例如 0 2 4 ... 22 1 3 5 ...),在这种情况下我不确定要排除什么(编辑:解决方案是:export GOMP_CPU_AFFINITY="0-17 20-24
。查看评论)。
至于为什么26个线程不会有问题我只能猜测。 OpenMP 可以选择将线程迁移到不同的内核。您的系统可以运行 24 个逻辑线程。我从来没有找到将线程数设置为大于逻辑线程数的值的原因(事实上,在我的矩阵乘法代码中,我将线程数设置为物理内核数,因为超线程会产生更差的结果).也许当您将线程数设置为大于逻辑核心数的值时,OpenMP 决定在它选择时迁移线程是可以的。如果它将您的线程从以 100% 运行的核心迁移出去,那么问题可能会消失。您可以通过使用 OMP_PROC_BIND 禁用线程迁移来对此进行测试
关于c - 特定线程数的 OpenMP 急剧减速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21792738/
我是一名优秀的程序员,十分优秀!