CUDAでニューロ評価関数を動かすのは難しいかも
こういうソースを書いて、ホスト(CPU)・デバイス(GPU)間のデータ転送・カーネル関数実行回数を計測してみました。
float D_h, *D_d; cudaMalloc( (void **) &D_d, sizeof( float ) ); // タイマー実行 unsigned int timer; cutCreateTimer( &timer ); cutStartTimer( timer ); const size_t MC = 1000 * 10; for( size_t i = 0; i < MC; i++ ){ D_h = 3.14; cudaMemcpy( D_d, &D_h, sizeof( float ), cudaMemcpyHostToDevice ); ping<<<1,1>>>( D_d ); cudaMemcpy( &D_h, D_d, sizeof( float ), cudaMemcpyDeviceToHost ); } // タイマー停止 cudaThreadSynchronize(); cutStopTimer( timer ); // 経過時間出力 double elapsedTime = cutGetTimerValue( timer ) * 1.0e-03; printf( "%f sec\n", elapsedTime ); printf( "%f times/sec\n", MC / elapsedTime );
転送するのは両方向ともfloat一個で、カーネルでは加算一回だけを実行(なので、すぐ終わる)。
んで、転送・加算・転送の繰り返し回数は、秒間6,000回強。つまり、この回数が評価関数呼び出し/秒の上限。
いくらなんでも6kNPSじゃぁ厳しいです。困った。
となると、ホストで探索・デバイスで評価関数って切り分けをやめて、探索もある程度デバイスで動かす必要あり?
ただ、そうなると合法手生成とか含めて色々と移植しないといけないんで、かなり冒険になりますね。うーん。