向量OpenMP-C的矩阵乘法

向量OpenMP-C的矩阵乘法,c,openmp,C,Openmp,我正在尝试用C(OpenMP)编写向量乘法矩阵 但当我添加处理器时,我的程序会变慢 1 proc - 1,3 s 2 proc - 2,6 s 4 proc - 5,47 s 我在我的电脑(CoreI5)和我们学校的集群上测试了这个,结果是一样的(程序变慢) 这是我的代码(矩阵是10000 x 10000),向量是10000: double start_time = clock(); #pragma omp parallel private(i) num_threads(4) { ti

我正在尝试用C(OpenMP)编写向量乘法矩阵 但当我添加处理器时,我的程序会变慢

1 proc - 1,3 s
2 proc - 2,6 s
4 proc - 5,47 s
我在我的电脑(CoreI5)和我们学校的集群上测试了这个,结果是一样的(程序变慢)

这是我的代码(矩阵是10000 x 10000),向量是10000:

double start_time = clock();
#pragma omp parallel private(i) num_threads(4)
{
    tid = omp_get_thread_num();
    world_size = omp_get_num_threads();
    printf("Threads: %d\n",world_size);

    for(y = 0; y < matrix_size ; y++){
        #pragma omp parallel for private(i) shared(results, vector, matrix)
        for(i = 0; i < matrix_size; i++){
                results[y] = results[y] + vector[i]*matrix[i][y];   
        }
    }
}
double end_time = clock();
double result_time = (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time: %f\n", result_time);
double start_time=clock();
#pragma omp并行专用(i)num_线程(4)
{
tid=omp_get_thread_num();
world_size=omp_get_num_threads();
printf(“线程:%d\n”,世界大小);
对于(y=0;y

我的问题是:有什么错误吗?对我来说,这似乎很简单,应该会加快速度。我已经有一段时间没有做过任何并行编程了,也没有做过任何数学计算,但是你不想并行分割矩阵的行,而不是列吗

如果您尝试以下操作,会发生什么情况:

double start_time = clock();
#pragma omp parallel private(i) num_threads(4)
{
tid = omp_get_thread_num();
world_size = omp_get_num_threads();
printf("Threads: %d\n",world_size);

#pragma omp parallel for private(y) shared(results, vector, matrix)
for(y = 0; y < matrix_size ; y++){

    for(i = 0; i < matrix_size; i++){
            results[y] = results[y] + vector[i]*matrix[i][y];   
    }
}
}
double end_time = clock();
double result_time = (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time: %f\n", result_time);
double start_time=clock();
#pragma omp并行专用(i)num_线程(4)
{
tid=omp_get_thread_num();
world_size=omp_get_num_threads();
printf(“线程:%d\n”,世界大小);
#pragma omp并行专用(y)共享(结果、向量、矩阵)
对于(y=0;y

另外,您确定使用
openMP
编译和链接一切正常吗?

我已经有一段时间没有做过任何并行编程了,也没有做过任何数学计算,但是您不想并行分割矩阵的行,而不是列吗

如果您尝试以下操作,会发生什么情况:

double start_time = clock();
#pragma omp parallel private(i) num_threads(4)
{
tid = omp_get_thread_num();
world_size = omp_get_num_threads();
printf("Threads: %d\n",world_size);

#pragma omp parallel for private(y) shared(results, vector, matrix)
for(y = 0; y < matrix_size ; y++){

    for(i = 0; i < matrix_size; i++){
            results[y] = results[y] + vector[i]*matrix[i][y];   
    }
}
}
double end_time = clock();
double result_time = (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time: %f\n", result_time);
double start_time=clock();
#pragma omp并行专用(i)num_线程(4)
{
tid=omp_get_thread_num();
world_size=omp_get_num_threads();
printf(“线程:%d\n”,世界大小);
#pragma omp并行专用(y)共享(结果、向量、矩阵)
对于(y=0;y

另外,您确定使用
openMP编译和链接时一切正常吗?

您有一个典型的缓存冲突案例

假设CPU上的缓存线可能有64字节长。让一个处理器/核心写入前4个字节(
float
)会导致每隔一个一级/二级缓存线失效,也可能是三级缓存线失效。这是一大笔开销

更好地划分数据

 #pragma omp parallel for private(i) shared(results, vector, matrix) schedule(static,16)
我们应该做到这一点。如果这没有帮助,请增加chunksize

另一种优化方法是在将结果刷新到内存之前将其本地存储

此外,这是一个OpenMP的东西,但您不需要为循环启动一个新的并行区域(每次提到
parallel
都会启动一个新团队):

#pragma omp并行默认值(无)\
共享(向量、矩阵)\
firstprivate(矩阵大小)\
线程数(4)
{
int i,y;
#计划的pragma omp(静态,16)
对于(y=0;y
您有一个典型的缓存冲突案例

假设CPU上的缓存线可能有64字节长。让一个处理器/核心写入前4个字节(
float
)会导致每隔一个一级/二级缓存线失效,也可能是三级缓存线失效。这是一大笔开销

更好地划分数据

 #pragma omp parallel for private(i) shared(results, vector, matrix) schedule(static,16)
我们应该做到这一点。如果这没有帮助,请增加chunksize

另一种优化方法是在将结果刷新到内存之前将其本地存储

此外,这是一个OpenMP的东西,但您不需要为循环启动一个新的并行区域(每次提到
parallel
都会启动一个新团队):

#pragma omp并行默认值(无)\
共享(向量、矩阵)\
firstprivate(矩阵大小)\
线程数(4)
{
int i,y;
#计划的pragma omp(静态,16)
对于(y=0;y
我基本上已经回答了这个问题

当您写入
结果[y]
时,您有一个竞争条件。要解决这个问题,并且仍然并行化内部循环,您必须创建
结果[y]
的私有版本,并行填充它们,然后将它们合并到关键部分

在下面的代码中,我假设您使用的是
double
,将其替换为
float
int
或您正在使用的任何数据类型(请注意,您的内部循环遍历了
矩阵[I][y]
的第一个索引,这是缓存不友好的)

#pragma omp并行num_线程(4)
{
int y,i;
double*results\u private=(double*)calloc(矩阵大小,sizeof(double));
对于(y=0;y对于(y=0;y我基本上已经回答了这个问题

当您写入
结果[y]
时,您有一个竞争条件。要解决这个问题,并且仍然并行内部循环,您必须创建
的私有版本