2016-10-25 13 views
0

私は、OpenGLで、マウスに続く多くの粒子を持つ2Dニュートン重力シミュレーションを作成しています。すべての粒子を反復する1つのループの速度を変更しています。OpenMPマルチスレッドの提案

これはうまくいきますが、パフォーマンスはそれほど良くはありませんが、2 miliumの粒子で平均60fpsしか得られません(i7 6700kとgtx 970)。 だから、私はマルチスレッドがそれを改善する最善の方法だと思った。 これを行うために、私はOpenMP 2.0を使用しました(私はVisual Studioにあります)。 更新ループはその後、次のようになります。

#pragma omp parallel for 
    for (int i = 0; i < count; i++) 
    { 
     float vertX = WIDTH/2 * (vertices[i*2]+1); 
     float vertY = -HEIGHT/2*(vertices[i *2+ 1]+1)+HEIGHT; 

     float fact = (mouseX - vertX)*(mouseX - vertX) + (mouseY - vertY)*(mouseY - vertY) + 120; 
     glm::vec2 acc = 3.f/fact*(glm::vec2(mouseX, mouseY) - glm::vec2(vertX, vertY)) * (float)bPressed; 
     acc.y *= -1; 

     speed[i*2] += acc.x - speed[i*2]/200; 
     speed[i *2+ 1] += acc.y - speed[i *2+ 1]/200; 

     vertices[i*2] += speed[i*2]*dt; 
     vertices[i *2+ 1] += speed[i*2+1]*dt; 

    } 

パフォーマンスは(今私は130のFPSを得る)多くのことを増加したが、期待できないとして、8つのスレッド(インテルハイパースレッディングで4つのコア)と、実際に、私が期待しますそれは以前よりも8倍優れています。それは3倍良いです。 openMPで何か問題があるのですか?それとも、パフォーマンスが向上しないのですか?

+0

データを更新するのは、おそらくフレーム内で行うことだけではありません。あなたは他のすべてのものも考慮しなければなりません。データ転送は大きな問題になるかもしれません。したがって、GPU上で直接計算を行うことを検討し、マウス座標を転送するだけでよい場合もあります。 –

+0

N個のスレッドでN倍の改善を得ることは非常に困難です([Amdahl's law](https:// en.wikipedia.org/wiki/Amdahl%27s_law))、特にOSや他のアプリケーションがCPUの注意を奪うために戦っている場合には、レンダリングパイプラインとハードウェアにも限界があります。 – molbdnilo

答えて

1

あなたのコードは良く見えますが、すぐに改善するものはありませんが、あなたの期待は高すぎます。

  1. 多くのコードでは、ハイパースレッディングはではなく、となります。このコードが計算上の境界である場合、予想されるパフォーマンスの向上は4倍です。ハイパースレッディングは、レイテンシに拘束されている(つまり、プロセッサがメモリを待っていても、メモリ帯域幅が飽和していない)場合にのみ有効です。それでも、しばしば4倍のスピードアップをわずかに上回るだけです。
  2. あなたのスピードアップは、コード全体の並列化されていない部分によって制限される場合があります。明らかに、FPSに影響を与える並列ループの外側には、他のコードもたくさんあります。これは、Ahmdal's lawによって説明されています。
  3. プロセッサはターボ周波数を使用し、1つのコアだけがアクティブな場合は高速で実行されます。
  4. メモリや共有キャッシュによって部分的に制限されている可能性がありますが、スピードアップによってメモリ帯域幅が完全に制限されているわけではありません。

その他の最適化は、countとその他のコードに大きく依存します。具体的な提案が必要な場合は、コードを蒸留した[mcve]として提供する必要があります。