私は C++ と OpenCL で (リカレント) ニューラル ネットワークを使用して、深層学習の低レベルの経験を積んでいます。現在、単純な順伝播カーネルを使用していますが、パフォーマンスが異常に低下しています。セットアップは、ほとんどのディープ ラーニング セットアップと同様にメモリ制限があり、大まかなプロファイリングに基づいて、取得しているメモリ帯域幅は約 2 GB/s です。clGetDeviceInfo() を呼び出すと、オンボード GPU (GTX 960m) を使用していることを確認できます。clCreateBuffer() で割り当てているメモリがどうにかして CPU に到達し、この記事で示唆されているように転送速度が約 2 GB/s になるのではないかと思います。割り当てているバッファーは、GPU に対して大きすぎないようにする必要があります。最大のものは 1024*1024*4 バイト = 4 MB (重み) で、そのうち 12 個だけが作成されます。
いくつかのコンテキストを含む clCreateBuffer() への呼び出し:
NVector::NVector(int size) {
empty = false;
numNeurons = size;
activationsMem = clCreateBuffer(RNN::clContext, CL_MEM_READ_WRITE, sizeof(float) * numNeurons, NULL, NULL);
parametersMem = clCreateBuffer(RNN::clContext, CL_MEM_READ_WRITE, sizeof(float) * numNeurons, NULL, NULL);
derivativesMem = clCreateBuffer(RNN::clContext, CL_MEM_READ_WRITE, sizeof(float) * numNeurons, NULL, NULL);
}
//...
void NVector::connect(NVector& other) {
int numWeights = other.numNeurons * numNeurons;
cl_mem weightMem = clCreateBuffer(RNN::clContext, CL_MEM_READ_WRITE, sizeof(float) * numWeights, NULL, NULL);
float weightAmplitude = 0.2f;
float* weightData = new float[numWeights];
for (int i = 0; i < numWeights; i++) {
weightData[i] = ((rand() % 256) / 256.0f - 0.5f) * weightAmplitude;
}
clEnqueueWriteBuffer(RNN::clQueue, weightMem, CL_TRUE, 0, sizeof(float) * numWeights, weightData, 0, NULL, NULL);
connections.push_back(&other);
weightsMem.push_back(weightMem);
}
OpenCL がアクティブなデバイスではなく CPU にメモリを割り当てる場合、どのような理由がありますか? GPU にメモリを強制的に割り当てるにはどうすればよいですか?
編集: 簡単なテストで、メモリ帯域幅のこの値が得られました。これは、CPU と GPU の間で推奨される 5 ~ 6 GB/秒の帯域幅に従っています。
operating device name: GeForce GTX 960M
2.09715 seconds
1.00663e+10 bytes
4.8e+09 bytes / second
Press any key to continue . . .