我将开始学习OpenMP,并将其用于并行计算,并测试以下代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int i,j,k,a = -59, b = 19,N,R;
struct timeval T1, T2;
long delta_ms;
N = atoi(argv[1]);
float m1[N][N], m2[N][N], m3[N][N];
gettimeofday(&T1, NULL);
#pragma omp parallel for default(none) private(R,i,j,k) shared(N,b,a,m1, m2, m3)
for (R=0; R<100; R++)
{
srand(R);
#pragma omp parallel for default(none) private(i,j) shared(N,b,a,m1)
for (i = 0; i < N; i++){
for (j = 0; j < N; j++){
m1[i][j] = (float) rand() / RAND_MAX * (b - a + 1) + a;
}
}
#pragma omp parallel for default(none) private(i,j) shared(N,m1,m2)
for (i = 0; i < N; i++){
for (j = 0; j < N; j++){
m2[i][j] = m1[i][j] * 5;
}
}
#pragma omp parallel for default(none) private(i,j,k) shared(N,m1,m2,m3)
for(i = 0; i < N; i++){
for(j = 0; j < N; j++){
m3[i][j] = 0;
for(k = 0; k < N; k++){
m3[i][j] = m3[i][j] + (m1[i][k] * m2[k][j]);
}
}
}
}
gettimeofday(&T2, NULL);
delta_ms = 1000*(T2.tv_sec - T1.tv_sec) + (T2.tv_usec - T1.tv_usec)/1000;
printf("\nN=%d. Milliseconds passed: %ld\n", N, delta_ms);
return 0;
}
我的电脑的特点:
我使用虚拟机(Virtual Box)。我安装了Ubuntu 14.04。我的虚拟机使用3个CPU和1 Gb RAM。我使用的是gcc编译器,版本4.8
现在,我对以下情况大感兴趣:
我没有
-fopenmp
键:gcc -o code1 code1.c
编译我的代码。当我运行code1时,我看到:
N=300. Milliseconds passed: 13706
我用键
-fopenmp
:gcc -o code1 code1.c -fopenmp
编译代码。当我运行code1时,我看到:
N=300. Milliseconds passed: 4898
我用键
-fopenmp
编译我的代码,并且只使用一个#pragma omp for
:#pragma omp parallel for default(none) private(R,i,j,k) shared(N,b,a,m1, m2, m3)for (R=0; R<100; R++){...}
当我运行code1时,我看到:
N=300. Milliseconds passed: 4919
步骤2和3的结果相等。
有人可以向我解释为什么会这样吗?
我阅读了OpenMP的文档,但找不到答案。
最佳答案
检查OMP_NUM_THREADS环境变量。我曾经在VirtualBox遇到过这个问题,问题是此变量设置为1。
它应与CPU内核数相等(如果使用hypethreading,则应为x2)。