2015-03-03 51 views
1

我不能制作新的标签,但它应该在MANAGEDCUDA标签上,因为我使用该框架在C#中使用CUDA。在CUDA设备中的内存分配不是预期的

我分配2个INT阵列,该代码进行测试:

Console.WriteLine("Cells: "+sum+" Expected Total Memory (x4): "+sum*4); 
int temp= 0; 
temp = cntxt.GetFreeDeviceMemorySize(); 
Console.Write("\n Memory available before:" + cntxt.GetFreeDeviceMemorySize() + "\n"); 
CudaDeviceVariable<int> matrix = new CudaDeviceVariable<int>(sum); 
CudaDeviceVariable<int> matrixDir = new CudaDeviceVariable<int>(sum); 
Console.Write("\n Memory available after allocation:" + cntxt.GetFreeDeviceMemorySize() + "\n"); 
Console.WriteLine("Memory took: "+(temp - cntxt.GetFreeDeviceMemorySize())); 
Console.WriteLine("Diference between the expected and allocated: " + ((temp - cntxt.GetFreeDeviceMemorySize())-sum*8)); 

运行后我在控制台得到这个:

Console Run

+1

习惯问一个问题。我想你想知道为什么分配了大约3MB的数据后,出现了大约40KB的差异?存在与分配相关的粒度/开销,而且该设备具有类似于运行在其上的操作系统的东西,这需要设备存储器用于它自己的内务处理任务。 – 2015-03-03 01:13:20

+1

回答[tag:cuda]问题的用户池已经相对有限,进一步拆分标签只会使您的问题不太明显。 – 2015-03-03 01:21:45

回答

6

当你通过分配器(malloc分配内存, cudaMalloc,...),它需要跟踪您分配的特殊元数据结构中的字节。例如,此元数据可能包含分配的字节数和它们在内存中的位置,一些用于调整分配的填充以及缓冲区溢出检查。

为了减少管理开销,大多数现代分配器使用页面,也就是说,它们以固定大小的不可分割块分配内存。在许多主机系统上,这个大小默认为4 kB。

在您的具体情况中,看起来CUDA将以64 kB的页面为您的内存分配请求提供服务。也就是说,如果你要求56 kB,CUDA无论如何都会为你提供64 kB,而未使用的8 kB却是“浪费”的(从你的应用程序的角度来看)。

当您请求1552516字节(即23.7页)的分配时,运行时会改为为您提供24页(1572864字节):这是额外的20348字节。加倍(因为你有2个数组),这就是你的40696字节差异来自哪里。

注:页面大小因GPU和驱动程序版本而异。您可以试着自己找到它,或者搜索其他人发布的结果。无论如何,这是(据我所知)没有记录,因此,如果您打算将您的程序移植到便携式计算机上,则可能不会被依赖。