我正在学习如何使用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中的任何重要语法或概念。 谢谢!
答案 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处理线程占用的程度。