首页 文章

2D纹理的间距对齐

提问于
浏览
5

2D纹理是图像处理应用程序中CUDA的一个有用特性 . 要将音高线性存储器绑定到2D纹理,必须对齐存储器 . cudaMallocPitch 是对齐内存分配的一个很好的选择 . 在我的设备上, cudaMallocPitch 返回的音高是512的倍数,即内存是512字节对齐的 .

设备的实际对齐要求由 cudaDeviceProp::texturePitchAlignment 确定,我的设备上为32字节 .

My question is:

如果2D纹理的实际对齐要求是32字节,那么为什么 cudaMallocPitch 返回512字节对齐的内存?

这不是浪费记忆吗?例如,如果我创建一个大小为513 x 100的8位图像,它将占用1024 x 100字节 .

我在以下系统上遇到此行为:

1:华硕G53JW Windows 8 x64 GeForce GTX 460M CUDA 5酷睿i7 740QM 4GB内存

2:戴尔Inspiron N5110 Windows 7 x64 GeForce GT525M CUDA 4.2 Corei7 2630QM 6GB内存

2 回答

  • 3

    这是一个略微推测的答案,但请记住,有两个对齐属性,分配的音高必须满足纹理,一个用于纹理指针,一个用于纹理行 . 我怀疑 cudaMallocPitch 正在尊重前者,由 cudaDeviceProp::textureAlignment 定义 . 例如:

    #include <cstdio>
    
    int main(void)
    {
        const int ncases = 12;
        const size_t widths[ncases] = { 5, 10, 20, 50, 70, 90, 100,
            200, 500, 700, 900, 1000 };
        const size_t height = 10;
    
        float *vals[ncases];
        size_t pitches[ncases];
    
        struct cudaDeviceProp p;
        cudaGetDeviceProperties(&p, 0);
        fprintf(stdout, "Texture alignment = %zd bytes\n",
                p.textureAlignment);
        cudaSetDevice(0);
        cudaFree(0); // establish context
    
        for(int i=0; i<ncases; i++) {
            cudaMallocPitch((void **)&vals[i], &pitches[i], 
                widths[i], height);
            fprintf(stdout, "width = %zd <=> pitch = %zd \n",
                    widths[i], pitches[i]);
        }
    
        return 0;
    }
    

    在GT320M上给出以下内容:

    Texture alignment = 256 bytes
    width = 5 <=> pitch = 256 
    width = 10 <=> pitch = 256 
    width = 20 <=> pitch = 256 
    width = 50 <=> pitch = 256 
    width = 70 <=> pitch = 256 
    width = 90 <=> pitch = 256 
    width = 100 <=> pitch = 256 
    width = 200 <=> pitch = 256 
    width = 500 <=> pitch = 512 
    width = 700 <=> pitch = 768 
    width = 900 <=> pitch = 1024 
    width = 1000 <=> pitch = 1024
    

    我猜 cudaDeviceProp::texturePitchAlignment 适用于CUDA数组 .

  • 3

    在对内存分配进行了一些实验后,我终于找到了一个可以节省内存的工作解决方案 . 如果我强行对齐 cudaMalloc 分配的内存, cudaBindTexture2D 完美无缺 .

    cudaError_t alignedMalloc2D(void** ptr, int width, int height, int* pitch, int alignment = 32)
    {       
       if((width% alignment) != 0)
          width+= (alignment - (width % alignment));
    
       (*pitch) = width;
    
       return cudaMalloc(ptr,width* height);
    }
    

    此函数分配的内存为32字节对齐,这是 cudaBindTexture2D 的要求 . 我的内存使用量现在减少了16倍,所有使用2D纹理的CUDA功能也正常工作 .

    这是一个小的实用功能,用于获取当前选择的CUDA设备音调对齐要求 .

    int getCurrentDeviceTexturePitchAlignment()
    {
       cudaDeviceProp prop;
       int currentDevice = 0;
    
       cudaGetDevice(&currentDevice);
    
       cudaGetDeviceProperties(&prop,currentDevice);
    
       return prop.texturePitchAlignment;
    }
    

相关问题