我正在尝试优化我的内核函数,但遇到了一些问题。首先,这可能与Radeon R9(夏威夷)有关,但其他GPU设备也应该发生类似情况。
对于主机,我有两个平台选项。要么编译并作为x86程序运行,要么作为x64程序运行。根据我选择的平台不同,我会得到使用32位指针和指针算术或使用64位指针的不同编译内核。生成的IL代码显示了差异,在第一种情况下是
在第二种情况下,它是这样的:
在GPU上进行64位算术运算相当昂贵,需要消耗大量额外的VGPR。在我的情况下,64位指针版本需要8个额外的VGPR,并且有大约140个VALUInsts,如CodeXL所示。 性能总体上在我这种情况下慢了37%,在较慢的64位和较快的32位内核代码之间。除了内部指针算术之外,完全相同。我已经尝试过优化,但即使是普通的偏移量,我仍然被卡在很多ADD_U64 IL指令中,这些指令在ISA代码中产生两个指令:V_ADD_I32和V_ADDC_U32。当然,所有指针都需要双倍的私有内存空间(因此需要更多的VGPR)。
现在我的问题是:是否有一种方法可以“交叉”编译OpenCL内核,以便x64程序可以创建32位指针内核?我不需要在GPU中寻址那么多内存,因此寻址少于4 GiB的内存空间就可以了。由于我的主机也执行带有所有32个zmm寄存器的AVX-512指令,这只在x64模式下可用,因此x86程序不是一个选项。这使整个情况有点具有挑战性。
请不要回复为什么会这样。我完全知道为什么x64程序和内核会表现出这种方式。
对于主机,我有两个平台选项。要么编译并作为x86程序运行,要么作为x64程序运行。根据我选择的平台不同,我会得到使用32位指针和指针算术或使用64位指针的不同编译内核。生成的IL代码显示了差异,在第一种情况下是
prog kernel &__OpenCL_execute_kernel(
kernarg_u32 %_.global_offset_0,
kernarg_u32 %_.global_offset_1,
...
在第二种情况下,它是这样的:
prog kernel &__OpenCL_execute_kernel(
kernarg_u64 %_.global_offset_0,
kernarg_u64 %_.global_offset_1,
...
在GPU上进行64位算术运算相当昂贵,需要消耗大量额外的VGPR。在我的情况下,64位指针版本需要8个额外的VGPR,并且有大约140个VALUInsts,如CodeXL所示。 性能总体上在我这种情况下慢了37%,在较慢的64位和较快的32位内核代码之间。除了内部指针算术之外,完全相同。我已经尝试过优化,但即使是普通的偏移量,我仍然被卡在很多ADD_U64 IL指令中,这些指令在ISA代码中产生两个指令:V_ADD_I32和V_ADDC_U32。当然,所有指针都需要双倍的私有内存空间(因此需要更多的VGPR)。
现在我的问题是:是否有一种方法可以“交叉”编译OpenCL内核,以便x64程序可以创建32位指针内核?我不需要在GPU中寻址那么多内存,因此寻址少于4 GiB的内存空间就可以了。由于我的主机也执行带有所有32个zmm寄存器的AVX-512指令,这只在x64模式下可用,因此x86程序不是一个选项。这使整个情况有点具有挑战性。
好吧,我的备用解决方案是生成一个x86子进程,使用共享内存并充当编译门。但是如果OpenCL中有一个简单的标志或(AMD特定的)设置可以解决问题,我宁愿不这样做。
请不要回复为什么会这样。我完全知道为什么x64程序和内核会表现出这种方式。