cudaGraphicsGLRegisterImage gives cudaErrorMemoryAllocation
cudaGraphicsGLRegisterImage gives cudaErrorMemoryAllocation
场景
我正在创建两个相当大的,大小的OpenGL 3D纹理。第一个是单渠道16位纹理,第二个纹理有四个频道和8位texel。比我需要在CUDA中注册两个。
我正在处理的应用程序为32位。系统特征:Win 7 64bit,Nvidia geforce 540m 2GB
问题
使用512x512x391或更大的纹理时,我对cudaGraphicsGLRegisterImage
的呼叫给了我cudaErrorMemoryAllocation
,尽管此返回值甚至都不是由cudaGraphicsGLRegisterImage
文档指定的可能返回值列表的一部分。可以在第94页的第94页找到此列表。之前没有执行内存的操作。但是,它可以与较小的纹理一起使用,例如512x512x71。
在cudaGraphicsGLRegisterImage
调用告诉大约1778 MB之前,请查询免费设备内存。
审议
-
一个解释可能是返回值是某些先前调用的错误代码。我可以通过在
cudaGraphicsGLRegisterImage
调用之前放置cudaGetLastError
并检查其返回值来消除这种可能性:它给了我cudaSuccess
。 -
我已经执行了一些计算。两个3D纹理要求的内存是:
(512 * 512 * 391)texels *(4个频道 * 1个字节 1频道 * 2频道 * 2 bytes a texel)= 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位系统上测试您的程序。
- 没有找到相关文章