1

シナリオ

非常に大きく、同じサイズのOpenGL3Dテクスチャを2つ作成しています。1つ目はシングルチャネルの16ビットテクスチャで、2つ目は4つのチャネルとテクセルあたり8ビットです。2つをCUDAに登録する必要があります。

私が取り組んでいるアプリケーションは32ビットです。システムの特徴:Win 7 64ビット、NVIDIA GeForce 540M 2GB

問題

512x512x391以上のテクスチャを使用している場合、を呼び出すと。cudaGraphicsGLRegisterImagecudaErrorMemoryAllocation返されますが、この戻り値は、のドキュメントで指定されている可能な戻り値のリストの一部でもありませんcudaGraphicsGLRegisterImage。このリストは94ページにあります。これまでに実行されたメモリ拡張操作はありません。ただし、512x512x71などの小さなテクスチャでは機能します。

呼び出しの直前に空きデバイスメモリをクエリすると、cudaGraphicsGLRegisterImage約1778MBが空きであることがわかります。

審議

  1. 1つの説明は、戻り値が以前の呼び出しのエラーコードであるということかもしれません。基本的cudaGetLastErrorに、呼び出しの直前に権利を置き、そのcudaGraphicsGLRegisterImage戻り値を確認することで、この可能性を排除できます。これにより、が得られますcudaSuccess

  2. 私はいくつかの計算を実行しました。2つの3Dテクスチャに必要なメモリは次のとおりです。

    (512 * 512 * 391)テクセル*(4チャネル*テクセルあたり1バイト+1チャネル*テクセルあたり2バイト)= 586.5 MB

    特に私のグラフィックスデバイスには2GBの専用メモリがあるので、これはそれほど多くありません。

  3. また、プロセスによって取得された合計メモリをチェックして、これがこのWin32-2GBの制限の問題ではないことを確認しました。タスクマネージャーによると、プロセスの合計メモリサイズは約279 MBで、直前にcudaGraphicsGLRegisterImage呼び出し。

  4. この投稿によると、操作のメモリコストは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最初の呼び出しで失敗します。

4

1 に答える 1

1

あなたのコードスニペットは私には問題ないように見えます。ただし、32ビットシステムを使用しているとのことです。そしてそれが問題になる可能性があります:あなたのプロセスは2GiBのアドレス空間しか持っていませんでした。そして、このアドレス空間がどのように割り当てられたかによっては、十分な大きさの連続したスライスが残っていない可能性があります。したがって、まだ十分なメモリがある場合でも、使用可能なアドレス空間が不足している可能性があります。また、CUDAメモリのすべての部分がプロセスアドレス空間にマッピングされているため、デバイスメモリであっても、これが発生する可能性が非常に高くなります。

これは、アドレス空間の断片化として知られる32ビットシステムでよく知られている問題です。これは、実際には64ビットシステムの本当の利点です。アドレス可能なメモリの量はそれほど多くありませんが、メモリ管理を大幅に簡素化するアドレス空間のサイズは、いっぱいにするのが非常に難しいため、アドレス空間の断片化はありません。実用的な問題。

私の提案:64ビットシステムでプログラムをテストしてください。

于 2012-10-24T09:40:42.507 に答える