随着线程数量的增加,OpenMP的实现速度越来越慢

OpenMP implementation increasingly slow with thread count increase

本文关键字:OpenMP 实现 速度 越来越 增加 线程      更新时间:2023-10-16

我一直在努力学习使用OpenMP。然而,我的代码在串行中运行的速度似乎比并行更快。

事实上,使用的线程越多,计算时间就越慢。

为了说明这一点,我做了一个实验。我正在尝试进行以下操作:

long int C[num], D[num];
for (i=0; i<num; i++) C[i] = i;
for (i=0; i<num; i++){
for (j=0; j<N; j++) {
D[i] = pm(C[i]);
}
}

其中函数pm只是

int pm(int val) {
val++;
val--;
return val;
}

我并行实现了内部循环,并将运行时间作为内部循环迭代次数(N)和使用的线程数的函数进行了比较。实验代码如下。

#include <stdio.h>
#include <iostream>
#include <time.h>
#include "omp.h"
#include <fstream>
#include <cstdlib>
#include <cmath>
static long num = 1000;
using namespace std;
int pm(int val) {
val++;
val--;
return val;
}
int main() {
int i, j, k, l;
int iter = 8;
int iterT = 4;
long inum[iter];
for (i=0; i<iter; i++) inum[i] = pow(10, i); 
double serial[iter][iterT], parallel[iter][iterT];
ofstream outdata;
outdata.open("output.dat");
if (!outdata) {
std::cerr << "Could not open file." << std::endl;
exit(1);
}
"""Experiment Start"""
for (l=1; l<iterT+1; l++) {
for (k=0; k<iter; k++) {
clock_t start = clock();
long int A[num], B[num];
omp_set_num_threads(l);
for (i=0; i<num; i++) A[i] = i;
for (i=0; i<num; i++){
#pragma omp parallel for schedule(static)
for (j=0; j<inum[k]; j++) {
B[i] = pm(A[i]);
}
}  
clock_t finish = clock();
parallel[k][l-1] = (double) (finish - start) / 
CLOCKS_PER_SEC * 1000.0;
start =   clock();
long int C[num], D[num];
for (i=0; i<num; i++) C[i] = i;
for (i=0; i<num; i++){
for (j=0; j<inum[k]; j++) {
D[i] = pm(C[i]);
}
}
finish = clock();
serial[k][l-1] = (double) (finish - start) / 
CLOCKS_PER_SEC * 1000.0;
}
}
"""Experiment End"""

for (j=0; j<iterT; j++) {
for (i=0; i<iter; i++) {
outdata << inum[i] << " " << j + 1 << " " << serial[i][j]
<< " " << parallel[i][j]<< std::endl;
}
}
outdata.close();
return 0;
}

下面的链接是每个线程计数的log(T)与log(N)的关系图。

不同线程数和计算任务大小的运行时间图。

(我只是注意到串行和并行的图例标签是错误的)。

正如您所看到的,使用多个线程会大大增加时间。添加更多的线程会随着线程数量的增加而线性增加所花费的时间。

有人能告诉我发生了什么事吗?

谢谢!

Freakish关于pm()函数什么都不做的说法是正确的,编译器感到困惑。

此外,rand()函数在OpenMP for循环中的作用也不好。

添加函数sqrt(i)(i是循环索引),我实现了代码的预期加速。