cudaGraphicsGLRegisterImage gives cudaErrorMemoryAllocation

cudaGraphicsGLRegisterImage gives cudaErrorMemoryAllocation

本文关键字:cudaErrorMemoryAllocation gives cudaGraphicsGLRegisterImage      更新时间:2023-10-16

场景

我正在创建两个相当大的,大小的OpenGL 3D纹理。第一个是单渠道16位纹理,第二个纹理有四个频道和8位texel。比我需要在CUDA中注册两个。

我正在处理的应用程序为32位。系统特征:Win 7 64bit,Nvidia geforce 540m 2GB

问题

使用512x512x391或更大的纹理时,我对cudaGraphicsGLRegisterImage的呼叫给了我cudaErrorMemoryAllocation,尽管此返回值甚至都不是由cudaGraphicsGLRegisterImage文档指定的可能返回值列表的一部分。可以在第94页的第94页找到此列表。之前没有执行内存的操作。但是,它可以与较小的纹理一起使用,例如512x512x71。

cudaGraphicsGLRegisterImage调用告诉大约1778 MB之前,请查询免费设备内存。

审议

  1. 一个解释可能是返回值是某些先前调用的错误代码。我可以通过在cudaGraphicsGLRegisterImage调用之前放置cudaGetLastError并检查其返回值来消除这种可能性:它给了我cudaSuccess

  2. 我已经执行了一些计算。两个3D纹理要求的内存是:

    (512 * 512 * 391)texels *(4个频道 * 1个字节 1频道 * 2频道 * 2 bytes a texel)= 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位系统上测试您的程序。

相关文章:
  • 没有找到相关文章