シナリオ
非常に大きく、同じサイズのOpenGL3Dテクスチャを2つ作成しています。1つ目はシングルチャネルの16ビットテクスチャで、2つ目は4つのチャネルとテクセルあたり8ビットです。2つをCUDAに登録する必要があります。
私が取り組んでいるアプリケーションは32ビットです。システムの特徴:Win 7 64ビット、NVIDIA GeForce 540M 2GB
問題
512x512x391以上のテクスチャを使用している場合、を呼び出すと。cudaGraphicsGLRegisterImage
がcudaErrorMemoryAllocation
返されますが、この戻り値は、のドキュメントで指定されている可能な戻り値のリストの一部でもありませんcudaGraphicsGLRegisterImage
。このリストは94ページにあります。これまでに実行されたメモリ拡張操作はありません。ただし、512x512x71などの小さなテクスチャでは機能します。
呼び出しの直前に空きデバイスメモリをクエリすると、cudaGraphicsGLRegisterImage
約1778MBが空きであることがわかります。
審議
1つの説明は、戻り値が以前の呼び出しのエラーコードであるということかもしれません。基本的
cudaGetLastError
に、呼び出しの直前に権利を置き、そのcudaGraphicsGLRegisterImage
戻り値を確認することで、この可能性を排除できます。これにより、が得られますcudaSuccess
。私はいくつかの計算を実行しました。2つの3Dテクスチャに必要なメモリは次のとおりです。
(512 * 512 * 391)テクセル*(4チャネル*テクセルあたり1バイト+1チャネル*テクセルあたり2バイト)= 586.5 MB
特に私のグラフィックスデバイスには2GBの専用メモリがあるので、これはそれほど多くはありません。
また、プロセスによって取得された合計メモリをチェックして、これがこのWin32-2GBの制限の問題ではないことを確認しました。タスクマネージャーによると、プロセスの合計メモリサイズは約279 MBで、直前に
cudaGraphicsGLRegisterImage
呼び出し。この投稿によると、操作のメモリコストは
cudaGraphicsRegisterImage
非常に低くなければなりません。
いくつかのコード
2つの3Dテクスチャの取得:
glTexImage3D( GL_TEXTURE_3D, 0, GL_INTENSITY16
, size.x, size.y, size.z
, 0, GL_RED, GL_UNSIGNED_SHORT, bufferPtr );
glTexImage3D( GL_TEXTURE_3D, 0, GL_RGBA8
, size.x, size.y, size.z
, 0, GL_RGB, GL_BYTE, nullptr );
概要をわかりやすくするために、テクスチャの生成とバインディングを省略しました。
CUDAへのテクスチャ登録:
size_t free, total;
CHECK_CUDA( cudaMemGetInfo( &free, &total ) );
qDebug() << "Free Memory:" << free / ( 1024 * 1024 ) << "MB";
enum resourceIndices{ FIRST_RESOURCE = 0, SECOND_RESOURCE = 1 };
cudaGraphicsResource* resources[ 2 ];
CHECK_CUDA( cudaGetLastError() );
CHECK_CUDA( cudaGraphicsGLRegisterImage( &resources[ FIRST_RESOURCE ]
, firstTextureID
, GL_TEXTURE_3D
, cudaGraphicsRegisterFlagsReadOnly ) );
CHECK_CUDA( cudaGraphicsGLRegisterImage( &resources[ SECOND_RESOURCE ]
, secondTextureID
, GL_TEXTURE_3D
, cudaGraphicsRegisterFlagsSurfaceLoadStore ) );
マクロCHECK_CUDA
は単に戻り値をチェックし、例外をスローします。cudaGraphicsGLRegisterImage
最初の呼び出しで失敗します。