![](/img/trans.png)
[英]cuda, OpenGL interoperability: cudaErrorMemoryAllocation error on cudaGraphicsGLRegisterBuffer
[英]cudaGraphicsGLRegisterImage gives cudaErrorMemoryAllocation
我正在創建兩個非常大的,大小相等的OpenGL 3D紋理。 第一個是單通道16位紋理,第二個是四個通道,每個紋理像素有8位。 比我需要在CUDA中注冊其中兩個。
我正在處理的應用程序是32位。 系統特征:Win 7 64bit,NVIDIA GeForce 540M 2GB
當使用512x512x391或更大的紋理時,我對cudaGraphicsGLRegisterImage
調用給了我一個cudaErrorMemoryAllocation
,盡管此返回值甚至不是cudaGraphicsGLRegisterImage
文檔指定的可能返回值列表的一部分。 可以在第94頁的此處找到此列表。之前沒有執行過任何存儲器擴展操作。 但是,它確實適用於較小的紋理,例如512x512x71。
在調用cudaGraphicsGLRegisterImage
之前cudaGraphicsGLRegisterImage
查詢可用的設備內存,大約有1778 MB可用空間。
一種解釋可能是返回值是某些先前調用的錯誤代碼。 通過將cudaGetLastError
放在cudaGraphicsGLRegisterImage
調用之前並檢查其返回值,基本上可以消除這種可能性:它給了我cudaSuccess
。
我已經做了一些計算。 兩個3D紋理所需的內存為:
(512 * 512 * 391)像素*(4通道*每個texel 1字節+ 1通道*每個texel 2字節)= 586.5 MB
這不算多,尤其是我的圖形設備有2 GB專用內存。
我還檢查了該進程獲得的總內存,只是為了確保這不是Win32-2GB限制問題:根據任務管理器,該進程的總內存大小約為279 MB, cudaGraphicsGLRegisterImage
調用。
根據此帖子 , cudaGraphicsRegisterImage
操作的內存成本應該非常低。
采集兩個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
調用時失敗。
您的代碼段對我來說很好。 但是您說過您使用的是32位系統。 那可能是問題所在:您的進程僅獲得2GiB的地址空間。 根據此地址空間的分配方式,很可能沒有足夠大的連續切片。 因此,即使仍然有足夠的內存,您可能也已經用盡了可用的地址空間。 而且,由於每塊CUDA內存都映射到了進程地址空間,甚至是設備內存,這很可能會發生。
在32位系統上,這是一個眾所周知的問題,稱為地址空間碎片 。 這實際上是64位系統的真正好處:可尋址的內存不是那么多,但是地址空間的巨大規模極大地簡化了內存管理,因為很難填充它,因此不會出現地址空間碎片一個實際的問題。
我的建議:在64位系統上測試您的程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.