我运行了一个 OpenMP 程序来执行 Jacobi 方法,它运行得非常好,2 个线程的性能略高于 2x 1 个线程,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 包括超线程?)
谢谢您的帮助。