- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试优化我的内核功能,但遇到了一些问题。首先,这可能与 Radeon R9(夏威夷)相关,但其他 GPU 设备也应该发生这种情况。
<小时/>对于主机,我有两个平台选择。作为 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 个 VALUInst,如 CodeXL 所示。在我的例子中,较慢的 64 位内核代码和较快的 32 位内核代码的总体性能大约差 37%。除了内部指针运算之外,这是完全相同的。我尝试对此进行优化,但即使使用简单的偏移量,我仍然遇到很多 ADD_U64 IL 指令,这些指令在 ISA 代码中生成两条指令:V_ADD_I32 和 V_ADDC_U32。当然,所有指针都需要双倍私有(private)内存空间(因此需要更多 VGPR)。
<小时/>现在我的问题是:有没有办法“交叉”编译 OpenCL 内核,以便 x64 程序可以创建 32 位指针内核?我不需要解决GPU 中有那么多内存,因此寻址小于 4 GiB 的内存空间就可以了。由于我的主机还使用所有 32 个 zmm 寄存器执行 AVX-512 指令(仅在 x64 模式下可用),因此无法选择 x86 程序。这使得整个情况有点具有挑战性。
嗯,我的后备解决方案是生成一个使用共享内存并充当编译门的 x86 子进程。但如果 OpenCL 中的简单标志或(AMD 特定)设置可以解决问题,我宁愿不这样做。
<小时/>请不要以“为什么”的方式回复。我完全明白为什么 x64 程序和内核会这样。
最佳答案
我有几个想法,但由于不熟悉 AMD GPU OpenCL 实现的内部原理,所以我在黑暗中摸索。
您可以通过图像传递数据吗(即使不是)?在 Intel GPU 上,通过采样器提供了不同的路径,即使在 64 位版本中也可以避免 64 位算术。
AMD 是否有允许阻止读取和写入的扩展?如果编译器证明地址是统一的(标量),这会有所帮助。例如。类似 Intel Subgroups (启用一些 block IO)。在 Intel 上,这有助于避免在总线上传输 SIMD 的地址以进行分散/聚集(并且也节省寄存器空间)。
(这是一个延伸。)针对 OpenCL 1.2 或更低版本进行编译有帮助吗?即指定-cl-std=CL1.2
?如果编译器知道没有使用 SVM(>=OpenCL 2.0)并且要对程序运行保守分析以证明它没有对指针算术进行疯狂的操作,那么它可以在 32 位中进行算术并隐式添加相对于所有地址的 64 位相对偏移量(使 GPU 程序认为它正在使用 32 位地址)。
再说一遍,我对 AMD 的具体情况一无所知,但我能感受到您对这个问题的痛苦。
关于OpenCL "cross"-编译 x64/32 位指针 GPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38334448/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!