2011-02-24 202 views
1

在“使用OpenMP”一书中,C是一个错误的内存访问的例子,我认为这是我试图平行化高斯算法的主要问题。OpenMP C并行化算法

的例子看起来是这样的:

k= 0 ;  
for(int j=0; j<n ; j++) 
    for(int i = 0; i<n; i++) 
     a[i][j] = a[i][j] - a[i][k]*a[k][j] ; 

所以,我不明白为什么这会导致糟糕的内存访问。在C中,二维数组按行存储,并且在每一步中都会将新行从内存复制到缓存。

我想找到一个解决方案,但我没有得到一个很好的加速。我的尝试效果很小。

有人可以给我一个提示我可以做什么吗?

最简单的方法是交换for循环,但我想按列方式执行。

第二次尝试:

for(int j=0; j<n-1 ; j+=2) 
    for(int i = 0; i<n; i++) 
    { 
    a[i][j] = a[i][j] - a[i][k]*a[k][j] ; 
    a[i][j+1] = a[i][j+1] - a[i][k]*a[k][j+1] ; 
    } 

没有有所作为的。

第三次尝试:

for(int j=0; j<n ; j++) 
{ 
    d= a[k][j] ; 
    for(int i = 0; i<n; i++) 
    { 
    e = a[i][k] ; 
    a[i][j] = a[i][j] - e*d ; 
    } 
} 

THX很多

迎接斯特普

+1

您是否试过交换'for'循环的顺序? – 2011-02-24 17:57:57

+0

是的,我认为,但这不会是意图的解决方案。 btw谢谢大家的快速回复! – Stepp 2011-02-24 18:46:45

回答

0

使用平板阵列代替,例如:

#define A(i,j) A[i+j*ldA] 

for(int j=0; j<n ; j++) 
{ 
    d= A(k,j) ; 
    ... 
} 
+0

它有什么区别?二维数组实际上是长扁平数组。 – Andrey 2011-02-24 18:07:13

+0

@Andrey它使得列主要布局变得更容易。二维数组在很多层面上都很难看。 – Anycorn 2011-02-24 18:09:18

+0

试过这个......加速是一样的。没有区别。 – Stepp 2011-02-24 18:43:41

0

你的循环顺序会导致缓存错过每次迭代,正如你所指出的那样出。所以,只要将循环语句的顺序:

for (int i = 0; i < n; i++)  // now "i" is first 
    for (int j = 0; j < n; j++) 
     a[i][j] = a[i][j] - a[i][k]*a[k][j]; 

这将解决该行中a和变化只是列,这意味着你的内存访问将是连续的。

+0

Thx,这将是最简单的方法来解决这个问题,但我希望它能够以列方式工作。 – Stepp 2011-02-24 18:42:42