Jam*_*ter 3 parallel-processing gcc for-loop openmp
我正在使用gcc的openmp实现来尝试并行化程序.基本上,赋值是添加omp pragma以获得找到友好数字的程序的加速.
给出了原始的串行程序(如下所示,除了我最后添加注释的3行).我们必须首先只是外部循环,然后只是内部循环.外环非常简单,对于给定数量的处理器,我接近理想的加速.对于内循环,我的性能比原始的串行程序差得多.基本上我要做的是减少sum变量.
看看cpu的使用情况,我每个核心只使用了~30%.可能是什么导致了这个?程序是否在每次遇到omp parallel for子句时不断创建新线程?在减少障碍方面,还有更多的开销吗?或者它可能是内存访问问题(例如缓存抖动)?从我读到的大多数openmp线程的实现得到加速重用(例如汇集),所以我不太确定第一个问题是什么是错的.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <omp.h>
#define numThread 2
int main(int argc, char* argv[]) {
int ser[29], end, i, j, a, limit, als;
als = atoi(argv[1]);
limit = atoi(argv[2]);
for (i = 2; i < limit; i++) {
ser[0] = i;
for (a = 1; a <= als; a++) {
ser[a] = 1;
int prev = ser[a-1];
if ((prev > i) || (a == 1)) {
end = sqrt(prev);
int sum = 0;//added this
#pragma omp parallel for reduction(+:sum) num_threads(numThread)//added this
for (j = 2; j <= end; j++) {
if (prev % j == 0) {
sum += j;
sum += prev / j;
}
}
ser[a] = sum + 1;//added this
}
}
if (ser[als] == i) {
printf("%d", i);
for (j = 1; j < als; j++) {
printf(", %d", ser[j]);
}
printf("\n");
}
}
}
Run Code Online (Sandbox Code Playgroud)
thread teams
在进入并行部分时实例化OpenMP .实际上,这意味着每次内循环开始时都会重复创建线程.
要启用线程重用,请使用更大的并行部分(以控制团队的生命周期)并特别控制外部/内部循环的并行,如下所示:
test.exe 1 1000000
使用此修复程序的执行时间从43 秒降至22秒(并且线程数反映了numThreads定义的值+ 1
PS或许说明显而言,并行内环的并行化似乎不是一个合理的性能指标.但这可能是这项工作的重点,我不会批评这个问题.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <omp.h>
#define numThread 2
int main(int argc, char* argv[]) {
int ser[29], end, i, j, a, limit, als;
als = atoi(argv[1]);
limit = atoi(argv[2]);
#pragma omp parallel num_threads(numThread)
{
#pragma omp single
for (i = 2; i < limit; i++) {
ser[0] = i;
for (a = 1; a <= als; a++) {
ser[a] = 1;
int prev = ser[a-1];
if ((prev > i) || (a == 1)) {
end = sqrt(prev);
int sum = 0;//added this
#pragma omp parallel for reduction(+:sum) //added this
for (j = 2; j <= end; j++) {
if (prev % j == 0) {
sum += j;
sum += prev / j;
}
}
ser[a] = sum + 1;//added this
}
}
if (ser[als] == i) {
printf("%d", i);
for (j = 1; j < als; j++) {
printf(", %d", ser[j]);
}
printf("\n");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)