2016-09-12 4 views
0

OpenCLを使用して積分器を並列化するとき、ループ全体をカーネルに入れるのは悪い習慣ですか?OpenCL RK4とGPUの統合

私はC++で書いたRK4インテグレータをOpenCLに移動しようとしています。そのため、現在はOpenMPを使用しています。

私は、実行ごとに約700回のループ反復で、1000万回以上の独立した統合実行を実行する必要があります。私は現在ループをカーネルにストップコンディションで書き込んでいますが、期待通りのパフォーマンスは得られません。

現在のCLカーネルは、スニペット:

` 
while (inPos.z > -1.0f){ 
     cnt++; 
     //Eval 1 

     //Euler Velocity 
     vel1 = inVel + (inAcc * 0.0f); 
     //Euler Position 
     pos1 = inPos + (vel1 * 0.0f) + ((inAcc * 0.0f)*0.5f); 

     //Drag and accels 
     combVel = sqrt(pow(vel1.x, 2)+pow(vel1.y, 2)+pow(vel1.z, 2)); 
     //motionUtils::drag(netForce, combVel, mortSigma, outPos.z); 
     dragForce = mortSigma*1.225f*pow(combVel, 2); 
     //Normalise vector 
     normVel = vel1/combVel; 
     //Drag Components 
     drag = (normVel * dragForce)*-1.0f; 
     //Add Gravity force 
     drag.z+=((mortMass*9.801f)*-1.0f); 
     //Acceleration components 
     acc1 = drag/mortMass; 

     ... 

     //Taylor Expansion 
     tayVel = (vel1+((vel2+vel3)*2.0f)+vel4) * (1.0f/6.0f); 
     inAcc = (acc1+((acc2+acc3)*2.0f)+acc4) * (1.0f/6.0f); 
     tayPos = (pos1+((pos2+pos3)*2.0f)+pos4) * (1.0f/6.0f); 

     //Swap ready for next iteration 
     inPos = inPos + (tayVel * timeStep); 
     inVel = inVel + (inAcc * timeStep); 

` 任意の考え/提案を、はるかに高く評価します。

答えて

1

は遅い関数の高速化(およびより少ない正確​​な)バージョンを試す:

normVel = vel1 * combVel; 

sqrt(pow(vel1.x, 2)+pow(vel1.y, 2)+pow(vel1.z, 2)) 

native_rsqrt(vel1.x*vel1.x+vel1.y*vel1.y+vel1.z*vel1.z) 

normVel = vel1/combVel; 

0から

dragForce = mortSigma*1.225f*pow(combVel, 2); 

dragForce = mortSigma*1.225f*(combVel*combVel); 

drag = (normVel * dragForce)*-1.0f; 
    //Add Gravity force 
    drag.z+=((mortMass*9.801f)*-1.0f); 

drag = -normVel * dragForce; 
    //Add Gravity force 
    drag.z-=mortMass*9.801f; 

tayVel = (vel1+((vel2+vel3)*2.0f)+vel4) * (1.0f/6.0f); 
    inAcc = (acc1+((acc2+acc3)*2.0f)+acc4) * (1.0f/6.0f); 
    tayPos = (pos1+((pos2+pos3)*2.0f)+pos4) * (1.0f/6.0f); 
tayVel = (vel1+((vel2+vel3)*2.0f)+vel4) * (0.166666f); 
    inAcc = (acc1+((acc2+acc3)*2.0f)+acc4) * (0.166666f); 
    tayPos = (pos1+((pos2+pos3)*2.0f)+pos4) * (0.166666f); 

あなたはあまりにも多くの変数を使用している場合は、256から128または64にローカルワークグループサイズを小さくしようとすると、それらはループの外に使用されていない場合は、より多くのスレッドがで発行できるように、ループの中で彼らの宣言を置きますそれと同時に。

+0

これは負荷を助けました - ありがとうhuseyin – Dusted

+0

あなたの歓迎、またコンパイラ文字列から高速リラックスした数学オプションを有効にすることができます。 –

関連する問題