【发布时间】:2017-03-03 22:29:19
【问题描述】:
我有一个程序,它可以分成一些彼此没有数据依赖关系的部分。我想使用 OpenMP 在处理器的不同内核上运行这些部分。我已经尝试过使用下面的代码,但是在单核上执行比在多核上执行花费的时间更少。你能告诉我哪里出错了吗?
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
void serial(){
unsigned int a[10],b[10],c[10];
long long int i,j,k;
for(i=0;i<10;i++){
b[i]=rand();
c[i]=rand();
}
a[0]=b[0]-c[0];
a[1]=b[1]*c[1];
a[2]=b[2]^c[2];
a[3]=b[3]|c[3];
a[4]=(b[4]*5)+c[4];
a[5]=(!b[5])&c[5];
a[6]=b[6]+c[6];
a[7]=b[7]-c[7];
a[8]=b[8]&c[8];
a[9]=b[9]^c[9];
for(i=0;i<10;i++){
printf("a[%lld]=%u\t",i,a[i]);
}
}
void parallel(){
unsigned int a[10],b[10],c[10];
int num_thread;
long long int i,j,k;
for(i=0;i<10;i++){
b[i]=rand();
c[i]=rand();
}
#pragma omp parallel
{
int ID;
long long int i1;
ID=omp_get_thread_num();
if(ID==0){
printf("ID is %d\n",ID);
a[0]=b[0]-c[0];
a[1]=b[1]*c[1];
a[2]=b[2]^c[2];
a[3]=b[3]|c[3];
a[4]=(b[4]*5)+c[4];
}
else{
printf("ID is %d\n",ID);
a[5]=(!b[5])&c[5];
a[6]=b[6]+c[6];
a[7]=b[7]-c[7];
a[8]=b[8]&c[8];
a[9]=b[9]^c[9];
}
}
for(i=0;i<10;i++){
printf("a[%lld]=%u\t",i,a[i]);
}
}
void main(){
double time;
unsigned long long int clock1,clock2;
time=omp_get_wtime();
serial();
time=omp_get_wtime()-time;
printf("\nSerial time : %f \n",time);
time=omp_get_wtime();
parallel();
time=omp_get_wtime()-time;
printf("\nParallel time : %f\n",time);
}
当我运行上述代码时,并行程序的运行时间是串行程序的 4 倍。 编辑 #1 更新了代码
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
unsigned long long int N=1000;
unsigned long long int *a1,*b1,*c1,*d1;
void init(){ //just to put some random data
unsigned long long int i;
a1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
b1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
c1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
d1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int));
for(i=0;i<N;i++){
a1[i]=rand();
b1[i]=rand();
c1[i]=rand();
d1[i]=rand();
}
}
void seq(){//runs on one core
unsigned long long int i;
unsigned long long int a[N],b[N],c[N],d[N];
for(i=0;i<N;i++){
a[i]=a1[i];
b[i]=b1[i];
c[i]=c1[i];
d[i]=d1[i];
}
for(i=0;i<N;i++){
a[i]=a[i]+b[i];
}
for(i=0;i<N;i++){
c[i]=c[i]+d[i];
}
}
void parallel(){//runs on 2 cores
unsigned long long int i;
unsigned long long int a[N],b[N],c[N],d[N];
for(i=0;i<N;i++){
a[i]=a1[i];
b[i]=b1[i];
c[i]=c1[i];
d[i]=d1[i];
}
#pragma omp parallel
{
int ID;
ID=omp_get_thread_num();
if(ID==0){
for(i=0;i<N;i++){
a[i]=a[i]+b[i];
}
}
else{
for(i=0;i<N;i++){
c[i]=c[i]+d[i];
}
}
}
}
void main(){
init();
double time;
time=omp_get_wtime();
seq();
time=omp_get_wtime()-time;
printf("\n time for serial execution : %f\n",time);
time=omp_get_wtime();
parallel();
time=omp_get_wtime()-time;
printf("\ntime for parallel execution : %f\n",time);
}
并行执行仍然比串行执行慢两倍。 该程序在 Intel core2 处理器上运行。
【问题讨论】:
-
存在与并行化相关的开销,即使线程之间没有数据依赖关系。除了所有其他考虑因素之外,您提供的计算非常短;如果这种情况下的开销没有克服并行化带来的任何好处,我实际上会感到惊讶。
-
感谢您的回复。这不是我的实际问题,我把它放在这里是为了说明。我会更新代码。
-
你为什么不使用
#pragma omp parallel for,你在哪里指定它应该创建多少线程?如果您一遍又一遍地使用 3 个线程执行第二部分,则需要更长的时间。你得到的实际时间是多少? -
@KamiKaze 部分代码不相似。我想在两个不同的内核上运行代码的两个不同部分。我不明白在这种情况下使用#pragma omp parallel for 会有什么帮助。
-
我认为你的工作还不够。将 N 设置为 1000000。这可能就足够了。我参与了一个使用 pthrds 并行化神经网络的项目,除非神经网络实际上有数千个节点,否则并行化是浪费时间。今天的计算机速度非常快。
标签: c parallel-processing openmp