2016-10-14 69 views
0

-----示例代码-----------OpenACC的和高速缓存耕作

for (body1 = 0; body1 < NBODIES; body1 ++) { 
    for (body2=0; body2 < NBODIES; body2++) { 
    OUT[body1] += compute(body1, body2); 
    } 
} 

-----阻断代码------

for (body2 = 0; body2 < NBODIES; body2 += BLOCK) { 
    for (body1=0; body1 < NBODIES; body1 ++) { 
     for (body22=0; body22 < BLOCK; body22 ++) { 
     OUT[body1] += compute(body1, body2 + body22); 
     } 
    } 
} 

我插入OpenACC指令将代码卸载到GPU。 但表现正在下降。 我搜索了一些论文,他们得出结论,原因是OpenACC不能利用GPU中的共享内存。但我认为主要原因是耕作/阻塞阻止了平行。因为耕耘会带来数据依赖性。 如果OpenACC不提供或不鼓励代码耕种? 如果有一个解决方案或示例,耕耘技术可以改善OpenACC代码。

回答

1

OpenACC可以做自动和显式的平铺(通过tile子句),但是,我不认为这是你的问题。我看到的问题是由于依赖于“OUT [body1]”,body2循环不可并行化。 OpenACC的可并行执行标量减少,因此你可以尝试以下操作:

#pragma acc parallel loop 
    for (body1 = 0; body1 < NBODIES; body1 ++) { 
    sum = 0.0; 
    #pragma acc loop reduction(+:sum) 
    for (body2=0; body2 < NBODIES; body2++) { 
     sum += compute(body1, body2); 
    } 
    OUT[body1] += sum; 
    } 

当然,我猜在这里,如果这没有帮助,请张贴问题的compliable例子。如果您正在使用PGI,请发布编译器反馈消息(-Minfo = accel)。