我运行了一个OpenMP程序来执行Jacobi方法,它运行得非常好,2个线程执行略超过2x 1线程,4个线程比1个线程快2倍。 我觉得一切都很完美……直到我准确地达到了20,22和24个线程。 我一直把它分解,直到我有这个简单的程序
#include #include int main(int argc, char *argv[]) { int i, n, maxiter, threads, nsquared, execs = 0; double begin, end; if (argc != 4) { printf("4 argsn"); 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 secondsn", 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和CPU亲和力您可能需要首先列出偶数线程然后奇数(例如0 2 4 … 22 1 3 5 …)在这种情况下我不确定要排除什么(编辑:解决方案是: export GOMP_CPU_AFFINITY="0-17 20-24
。查看评论)。
至于为什么26个线程没有问题我只能猜测。 OpenMP可以选择将线程迁移到不同的核心。 您的系统可以运行24个逻辑线程。 我从来没有找到将线程数设置为大于逻辑线程数的值的理由(事实上在我的矩阵乘法代码中,我将线程数设置为物理内核数,因为超线程会导致更糟糕的结果)。 也许当您将线程数设置为大于逻辑核心数的值时,OpenMP决定在选择时迁移线程是可以的。 如果它将你的线程从100%运行的核心迁移出来,那么问题就会消失。 您可以通过使用OMP_PROC_BIND禁用线程迁移来测试它
需要了解更多c/c++开发分享OpenMP特定线程数急剧减速,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享OpenMP特定线程数急剧减速相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979280.html