Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization CUDA代码中的cmem[2]使用量异常大_Optimization_Cuda_Gpu - Fatal编程技术网

Optimization CUDA代码中的cmem[2]使用量异常大

Optimization CUDA代码中的cmem[2]使用量异常大,optimization,cuda,gpu,Optimization,Cuda,Gpu,我正在CUDA上编写一个(公认的本地内存密集型)代码,我已经过了开发阶段,进入了加速阶段。命令行分析器表明我的占用率(我认为)非常低(主要内核为0.083-0.417),我希望对此进行改进。不幸的是,计算工作需要大量的\uuuuu共享\uuuuu内存(每128个线程块16-20 kB)和一些寄存器(主要内核报告为63,尽管我不确定我是否实际使用了这么多…) 不过,我真正的问题是关于cmem[2]。下面是一个例子: 使用了8个寄存器,40字节cmem[0],51584字节cmem[2],368字节

我正在CUDA上编写一个(公认的本地内存密集型)代码,我已经过了开发阶段,进入了加速阶段。命令行分析器表明我的占用率(我认为)非常低(主要内核为0.083-0.417),我希望对此进行改进。不幸的是,计算工作需要大量的
\uuuuu共享\uuuuu
内存(每128个线程块16-20 kB)和一些寄存器(主要内核报告为63,尽管我不确定我是否实际使用了这么多…)

不过,我真正的问题是关于
cmem[2]
。下面是一个例子:

使用了8个寄存器,40字节cmem[0],51584字节cmem[2],368字节cmem[14],4字节cmem[16]

所有内核似乎都使用了大量的
cmem[2]
,我甚至不确定它是什么。我通过通常的
cudamaloc
调用在设备上存储了大量内存,并通过
cudaMemcpyToSymbol
调用在
\uuuu constant\uuuuuu
内存中存储了少量的双精度和指针(虽然没有接近50KB),但仅此而已。所以我的问题是:我究竟如何使用所有这些
cmem[2]
,它是否限制了我的内核占用率


另外,我正在运行GTX550TI,CUDA4.2和Ubuntu 10.04.4 64位。nvcc生成的可执行文件被包装在mpirun中,因为代码也是MPI并行的。

在费米体系结构上,CUDA驱动程序使用cmem[2]存储常量变量。同一模块中的所有函数共享相同的常量。这个固定银行的规模不会影响您的理论SM占用率或增加您的启动开销。如果超过最大大小(64KB),则会收到编译器错误

CUDA二进制实用程序cuobjdump可用于调试分配

如果文件sm20.cu具有以下常量

__constant__ float k_float_array[] = { 0.f, 1.f, 2.f, 3.f };
__constant__ double k_double_array[] = { 0.0, 1.0, 2.0, 3.0 };
__constant__ int k_int_array[] = { 0, 1, 2, 3 };

__global__ void empty_kernel(float* a)
{
    return;
}
你可以跑

cuobjdump.exe -elf sm20.cu.obj
可执行文件也可以用作参数。运行cuobjdump——帮助获取选项列表

此命令将产生以下输出

Fatbin elf code:
================
arch = sm_20
code version = [1,5]
producer = cuda
host = windows
compile_size = 32bit
identifier = c:/dev/constant/sm20.cu

32bit elf: abi=5, sm=20, flags = 0x140114
Sections:
Index Offset   Size ES Align   Type   Flags Link     Info Name
    1     34     a6  0  1    STRTAB       0    0        0 .shstrtab
    2     da     e9  0  1    STRTAB       0    0        0 .strtab
    3    1c4     80 10  4    SYMTAB       0    2        6 .symtab
    4    244     18  0  4 CUDA_INFO       0    3        0 .nv.info
    5    25c     20  0  4 CUDA_INFO       0    3        8 .nv.info._Z12empty_kernelPf
    6    27c     24  0  4  PROGBITS       2    0        8 .nv.constant0._Z12empty_kernelPf
    7    2a0     40  0  8  PROGBITS       2    0        0 .nv.constant2
    8    2e0     10  0  4  PROGBITS       6    3  2000007 .text._Z12empty_kernelPf
elf节.nv.constant2包含cmem[2]的内容。此大小为0x40==64字节,符合我的预期

.nv.constant2是第7节索引

.section .strtab

.section .shstrtab

.section .symtab
 index     value     size      info    other  shndx    name
   0          0        0        0        0      0     (null)
   1          0        0        3        0      8     .text._Z12empty_kernelPf
   2          0        0        3        0      6     .nv.constant0._Z12empty_kernelPf
   3          0        0        3        0      7     .nv.constant2
   4          0       16        1        0      7     k_float_array
   5         16       32        1        0      7     k_double_array
   6         48       16        1        0      7     k_int_array
   7          0       16       12       10      8     _Z12empty_kernelPf
.symtab包含定义的3个常量数组。shndx==7的所有符号都将位于.nv.constant2中

.nv.constant0._Z12empty_kernelPf
0x00000000  0x00000000  0x00000000  0x00000000  0x00000000
0x00000000  0x00000000  0x00000000  0x00000000

.nv.constant2
0x00000000  0x3f800000  0x40000000  0x40400000  0x00000000
0x00000000  0x00000000  0x3ff00000  0x00000000
0x40000000  0x00000000  0x40080000  0x00000000
0x00000001  0x00000002  0x00000003
.nv.constant2定义节中的二进制数据。这与声明的常量变量相匹配。如果有很多常量,.symtab部分会标识每个符号的偏移量和大小

// skipping .nv.info and .text

cuobjdump可用于转储PTX和SASS代码。PTX和SASS汇编可用于确定哪些内核使用常量。

在费米体系结构上,CUDA驱动程序使用cmem[2]存储常量变量。同一模块中的所有函数共享相同的常量。这个固定银行的规模不会影响您的理论SM占用率或增加您的启动开销。如果超过最大大小(64KB),则会收到编译器错误

CUDA二进制实用程序cuobjdump可用于调试分配

如果文件sm20.cu具有以下常量

__constant__ float k_float_array[] = { 0.f, 1.f, 2.f, 3.f };
__constant__ double k_double_array[] = { 0.0, 1.0, 2.0, 3.0 };
__constant__ int k_int_array[] = { 0, 1, 2, 3 };

__global__ void empty_kernel(float* a)
{
    return;
}
你可以跑

cuobjdump.exe -elf sm20.cu.obj
可执行文件也可以用作参数。运行cuobjdump——帮助获取选项列表

此命令将产生以下输出

Fatbin elf code:
================
arch = sm_20
code version = [1,5]
producer = cuda
host = windows
compile_size = 32bit
identifier = c:/dev/constant/sm20.cu

32bit elf: abi=5, sm=20, flags = 0x140114
Sections:
Index Offset   Size ES Align   Type   Flags Link     Info Name
    1     34     a6  0  1    STRTAB       0    0        0 .shstrtab
    2     da     e9  0  1    STRTAB       0    0        0 .strtab
    3    1c4     80 10  4    SYMTAB       0    2        6 .symtab
    4    244     18  0  4 CUDA_INFO       0    3        0 .nv.info
    5    25c     20  0  4 CUDA_INFO       0    3        8 .nv.info._Z12empty_kernelPf
    6    27c     24  0  4  PROGBITS       2    0        8 .nv.constant0._Z12empty_kernelPf
    7    2a0     40  0  8  PROGBITS       2    0        0 .nv.constant2
    8    2e0     10  0  4  PROGBITS       6    3  2000007 .text._Z12empty_kernelPf
elf节.nv.constant2包含cmem[2]的内容。此大小为0x40==64字节,符合我的预期

.nv.constant2是第7节索引

.section .strtab

.section .shstrtab

.section .symtab
 index     value     size      info    other  shndx    name
   0          0        0        0        0      0     (null)
   1          0        0        3        0      8     .text._Z12empty_kernelPf
   2          0        0        3        0      6     .nv.constant0._Z12empty_kernelPf
   3          0        0        3        0      7     .nv.constant2
   4          0       16        1        0      7     k_float_array
   5         16       32        1        0      7     k_double_array
   6         48       16        1        0      7     k_int_array
   7          0       16       12       10      8     _Z12empty_kernelPf
.symtab包含定义的3个常量数组。shndx==7的所有符号都将位于.nv.constant2中

.nv.constant0._Z12empty_kernelPf
0x00000000  0x00000000  0x00000000  0x00000000  0x00000000
0x00000000  0x00000000  0x00000000  0x00000000

.nv.constant2
0x00000000  0x3f800000  0x40000000  0x40400000  0x00000000
0x00000000  0x00000000  0x3ff00000  0x00000000
0x40000000  0x00000000  0x40080000  0x00000000
0x00000001  0x00000002  0x00000003
.nv.constant2定义节中的二进制数据。这与声明的常量变量相匹配。如果有很多常量,.symtab部分会标识每个符号的偏移量和大小

// skipping .nv.info and .text

cuobjdump可用于转储PTX和SASS代码。PTX和SASS汇编可用于确定哪些内核正在使用常量。

您是否查看了内核编译的PTX输出(
nvcc-PTX
)?这可能会给你一些提示。你的内核有很多参数还是复杂的结构参数?你能提供至少一个cmem使用量大的内核的原型吗?还有用于编译的nvcc命令行。您看过内核编译的PTX输出了吗(
nvcc-PTX
)?这可能会给你一些提示。你的内核有很多参数还是复杂的结构参数?你能提供至少一个cmem使用量大的内核的原型吗?还有用于编译的nvcc命令行。