对于矩阵初始化,openmp比串行慢

时间:2014-11-18 22:50:59

标签: c openmp

我正在学习如何使用openmp但是通过执行以下操作会变得更慢。基本上,我只是想初始化一个巨大的二维矩阵。

219     int **scoreMatrix = malloc(sizeof(int *) * (strlen(seq1)+1));
220 
221     int i,j = 0;
222     omp_set_num_threads(6);
224 #pragma omp parallel private(i,j) 
225 {
226     int std = omp_get_thread_num();
227     //Initialize matrix
228     for(i = std; i < strlen(seq1)+1; i=i+nthreads){
229         scoreMatrix[i] = malloc(sizeof(int) * (strlen(seq2)+1));
230         for(j = 0; j < strlen(seq2)+1; j++){
231             scoreMatrix[i][j] = 0;
232         }
233     }
234 }

请告诉我,我是否遗漏了OpenMP中的任何重要语法或概念。 谢谢!

2 个答案:

答案 0 :(得分:1)

虽然自从我上次使用OpenMP以来已经有一段时间了,但你的问题很可能归结为开销,而且每个线程所做的工作都相当小。你有每个线程设置做1/6的mallocs和1/6的集合为0.对于这样的问题你应该考虑seq1和seq2有多大以及实际并行执行了多少工作。例如,标准malloc的内存分配可能是一个争用点,例如参见此question并进行更详细的分析。如果大部分工作是由malloc完成的,并且因此没有在很大程度上并行完成,那么你就不会为支付线程初始化的开销而获得更多的加速。如果确实需要,那么使用不同的分配器可能会有所改进。将内存区域设置为0可以在线程之间进行拆分,但与分配相比,它几乎肯定非常快。在第229行设置scoreMatrix [i]时可能还存在一些缓存一致性成本,因为该缓存行在线程之间共享。

使用OpenMP和MPI时,重要的是要记住简单地启动计算的并行部分会涉及开销,并且因为没有太多工作的块,即使它们可能是高度并行的,也可能不值得并行化。当您在阵列上进行计算时,您更有可能看到一个好处。

对于归零内存,一般来说,最好的方法可能是memset,但是你的编译器可能会优化230&amp; 231做类似的事情。

答案 1 :(得分:0)

最好让openmp使用#pragma omp parallel for

为您进行并行化
int **scoreMatrix = malloc(sizeof(int *) * (strlen(seq1)+1));

int i,j = 0;
omp_set_num_threads(6);

#pragma omp parallel for private(i,j) 
for(i = 0; i < strlen(seq1)+1; ++i){
    scoreMatrix[i] = malloc(sizeof(int) * (strlen(seq2)+1));
    for(j = 0; j < strlen(seq2)+1; ++j){
        scoreMatrix[i][j] = 0;
    }
}

这可能会影响openmp处理线程占用的程度。