CUDA 6.0と、CUDA SDKにバンドルされているOpenCL実装を使用しています。プラットフォームごとに2つの同一のカーネルがあります(プラットフォーム固有のキーワードが異なります)。それらはグローバルメモリのみを読み書きし、各スレッドは異なる場所にあります。 CUDAの起動構成は200 blocks of 250 threads (1D)
であり、OpenCLの構成に直接対応しています-50,000 global work size and 250 local work size
。
OpenCLコードはより高速に実行されます。これは可能ですか、それとも間違ったタイミングですか?私の理解では、NVIDIAのOpenCL実装はCUDAの実装に基づいています。 OpenCLを使用すると、パフォーマンスが約15%向上します。
NVIDIAで実装されているCUDAとOpenCLの違い、そしておそらくいくつかの違いが見られる理由を教えていただければ幸いです。
最新のGPUで実行されるカーネルは、ほとんど計算にバインドされておらず、ほとんどの場合、メモリ帯域幅にバインドされています。 (メモリへの利用可能なパスと比較して、非常に多くの計算コアが実行されているためです。)
つまり、特定のカーネルのパフォーマンスは通常、特定のアルゴリズムが示すメモリアクセスパターンに大きく依存します。
実際には、これにより、事前に予想されるパフォーマンスを予測(または理解)することが非常に困難になります。
観察された違いは、OpenCL対CUDAツールチェーンによって行われた異なる最適化に起因する2つのカーネル間のメモリアクセスパターンの微妙な違いが原因である可能性があります。
GPUカーネルを最適化する方法を学ぶには、利用可能なメモリキャッシュハードウェアの詳細と、それを最大限に活用する方法を学ぶ必要があります。 (たとえば、「ローカル」メモリキャッシュを戦略的に使用するのではなく、常にOpenCLの「グローバル」メモリに直接アクセスします)。