簡體   English   中英

cudaGraphicsGLRegisterImage給出cudaErrorMemoryAllocation

[英]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可用空間。

商議

  1. 一種解釋可能是返回值是某些先前調用的錯誤代碼。 通過將cudaGetLastError放在cudaGraphicsGLRegisterImage調用之前並檢查其返回值,基本上可以消除這種可能性:它給了我cudaSuccess

  2. 我已經做了一些計算。 兩個3D紋理所需的內存為:

    (512 * 512 * 391)像素*(4通道*每個texel 1字節+ 1通道*每個texel 2字節)= 586.5 MB

    不算多,尤其是我的圖形設備有2 GB專用內存。

  3. 我還檢查了該進程獲得的總內存,只是為了確保這不是Win32-2GB限制問題:根據任務管理器,該進程的總內存大小約為279 MB, cudaGraphicsGLRegisterImage調用。

  4. 根據此帖子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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM