0
私はCUDAの新機能で、テストプログラムを作成しようとしています。 私はGeForce GT 520カードでアプリケーションを実行していますが、パフォーマンスが非常に悪くなっています。CUDAでのメモリアクセス性能が非常に悪い
アプリケーションは、各行が別のスレッドで処理されるイメージを処理するために使用されます。 以下は、アプリケーションの簡略化されたバージョンです。実際のアプリケーションでは、すべての定数は実際には呼び出し元である変数です。
以下のコードを実行すると、の実行には12時間以上かかるが必要です。
しかしl_SrcIntegral
がローカル配列(これはコメント行に表示される)として定義されている場合のmalloc /フリーを使用してとは対照的に、それが実行を完了するために1秒より未満を要します。
実際の配列のサイズは動的であり(1700ではなく)、このローカル配列は実際のアプリケーションでは使用できません。
どのようにこの簡単なコードのパフォーマンスを向上させるためのアドバイスをいただければ幸いです。
#include "cuda_runtime.h"
#include <stdio.h>
#define d_MaxParallelRows 320
#define d_MinTreatedRow 5
#define d_MaxTreatedRow 915
#define d_RowsResolution 1
#define k_ThreadsPerBlock 64
__global__ void myKernel(int Xi_FirstTreatedRow)
{
int l_ThreadIndex = blockDim.x * blockIdx.x + threadIdx.x;
if (l_ThreadIndex >= d_MaxParallelRows)
return;
int l_Row = Xi_FirstTreatedRow + (l_ThreadIndex * d_RowsResolution);
if (l_Row <= d_MaxTreatedRow) {
//float l_SrcIntegral[1700];
float* l_SrcIntegral = (float*)malloc(1700 * sizeof(float));
for (int x=185; x<1407; x++) {
for (int i=0; i<1700; i++)
l_SrcIntegral[i] = i;
}
free(l_SrcIntegral);
}
}
int main()
{
cudaError_t cudaStatus;
cudaStatus = cudaSetDevice(0);
int l_ThreadsPerBlock = k_ThreadsPerBlock;
int l_BlocksPerGrid = (d_MaxParallelRows + l_ThreadsPerBlock - 1)/l_ThreadsPerBlock;
int l_FirstRow = d_MinTreatedRow;
while (l_FirstRow <= d_MaxTreatedRow) {
printf("CUDA: FirstRow=%d\n", l_FirstRow);
fflush(stdout);
myKernel<<<l_BlocksPerGrid, l_ThreadsPerBlock>>>(l_FirstRow);
cudaDeviceSynchronize();
l_FirstRow += (d_MaxParallelRows * d_RowsResolution);
}
printf("CUDA: Done\n");
return 0;
}
'l_SrcIntegral'をローカルメモリ配列として定義すると、コンパイラの最適化によってカーネル全体がなくなり、空のスタブを実行しなくなります。 CUDAコンパイラは、グローバルメモリ書き込みに寄与しないデッドコードを除去するのに非常に積極的です。ですから、私は2つのケースのパフォーマンスの違いをあまり読みません。 – talonmies
@talonmies、あなたは、メモリの書き込みが最適化されないようにサンプルを改善する必要があると言いますか?私はそれをやろうとします。ありがとう。 – MarkM
@talonmies、ローカルメモリ配列についてfoget。上記のコードを20秒以上実行するよりも早く実行するためのヒントはありますか? – MarkM