我写了一个矩阵向量乘法的代码。矩阵根据线程的数量划分成若干行,每个块乘以向量,向量存储在线程专用的数组中。但是我的加速非常糟糕。对于大小为16×16的矩阵,它低于1.OpenMp代码的性能
这是否可以归因于以下事实:我将外部矩阵和向量声明为共享变量,并且可能在每个线程试图读取时导致竞争条件/错误共享矩阵和向量的值?
我有点混淆错误分享和竞争条件。
#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#define SIZE 128 // The size should be divisible by thenumber of threads
int main(int argc, char *argv[]) {
int thread_count = strtol(argv[1],NULL,10);
// Declare the variables
int i,j;
long A[SIZE][SIZE], b[SIZE],V[SIZE]={0};
//long Vect[SIZE]={0};
double start, end;
// Generate a matrix of size mxm
for (i=0; i<SIZE; i++)
{ for (j=0; j<SIZE; j++)
A[i][j] = i+j;
}
printf("The Matrix is:\n");
// Print the Matrix
for (i=0; i<SIZE; i++)
{ for (j=0; j<SIZE; j++)
{
printf("%12ld", A[i][j]);
}
printf("\n");
}
// Generate a vector of size m
for (i=0; i<SIZE; i++)
b[i] = i;
printf("The vector is: \n");
// Print a vector
for (i=0; i<SIZE; i++)
printf("%12ld\n", b[i]);
start = omp_get_wtime();
//omp_set_num_threads(NUM_THREADS);
#pragma omp parallel num_threads(thread_count)
{
int i,j,k, id, nthrds;
long Vect[SIZE]={0};
id = omp_get_thread_num();
nthrds = omp_get_num_threads();
for (i=id*SIZE/nthrds; i<(id*SIZE/nthrds + SIZE/nthrds); i++)
{ Vect[i] = 0;
{
for (j=0; j<SIZE; j++)
Vect[i] += A[i][j]*b[j];
}
}
#pragma omp critical
{
for (k=0; k<SIZE; k++)
V[k] += Vect[k];
}
}
end = omp_get_wtime();
printf("The vector obtained after multiplication is:\n");
for (i=0; i<SIZE; i++)
printf("%12ld\n", V[i]);
printf("The time taken for calculation is: %lf\n", end - start);
return 0;
}
这很可能是一个工作量小(每个线程只做256/num_thread乘加),设定的开销多线程并行化的速度比并行化的速度更快。是的,在线程之间共享写入状态很可能使并行化开销更高。 – aruisdante 2015-02-24 18:04:32
欲了解更多关于虚假分享:http://stackoverflow.com/questions/9027653/openmp-false-sharing?rq=1。对于一般的OpenMP性能的一些有趣的讨论:http://stackoverflow.com/questions/10939158/openmp-performance?rq=1 – aruisdante 2015-02-24 18:10:44
@aruisdante没有共享写入,有共享读取 – 2015-02-24 21:39:31