在asm易失性嵌入式PTX指令中,为什么还要指定“内存”副作用?

刺柏

请考虑以下CUDA的Inline PTX Assebly指南(v10.2)的摘录

编译器假定一条asm()语句除更改输出操作数外没有任何副作用。为了确保在生成PTX期间不会删除或移动asm,应使用volatile关键字,例如:

asm volatile ("mov.u32 %0, %%clock;" : "=r"(x));

通常,将写入的任何内存都将指定为out操作数,但是如果对用户内存有隐藏的副作用(例如,通过操作数间接访问内存位置),或者要停止任何内存优化在生成PTX期间执行的asm()语句周围,您可以在第三个冒号之后添加“内存”修饰符规范。

这听起来像两者 volatile:: "memory"并且旨在指示内存中的副作用。现在,理所当然,可能会出现非内存副作用(例如trap;)。但是-当我使用volatile过时,也指定:: "memory"是没有用/没有意义的吗?

稍微相关:使用内联PTX asm()指令时,“ volatile”有什么作用?

彼得·科德斯

volatile内联的asm语句被视为其输入纯函数:每次使用相同的显式输入运行时,都会提供相同的输出。

另外,没有任何"memory"障碍:不读取或写入未提及为输入或输出操作数的任何内容。

听起来像volatile和::“ memory”都是用来指示内存中的副作用。

不,volatile 只是意味着输出操作数不是输入操作数的纯函数。"memory"撞大多是正交的,没有通过暗示volatile

您引用的示例似乎正在读取%%clock周期计数器或每次都需要重新执行的内容,否则编译器可以执行CSE并将其吊起循环。您不想强迫编译器溢出/重新加载其在寄存器中的所有全局变量。volatile并不意味着内存有副作用,因此这只是此用例的证明。

这仍然是一个错误的ASM模板来读取或写入编译器背后的任何其他变量(不通过明确的"m""=m""+m"操作数),因为volatile并不意味着"memory"撞。

在GNU C内联汇编甚至"r"(pointer_variable)没有暗示指向的数据被读取或写入。例如,如果您对变量所做的全部工作就是将指向它的指针作为对asm不带"memory"麻烦语句的输入,则可以将其优化为无效存储我如何指示可以使用内联ASM参数*指向*的内存?

"memory"得到的编译器假定任何全局可到达的存储器(或通过指针输入可达)可能已被读出或写入,从而溢出/重装从围绕这样asm语句寄存器瓦尔。(除非转义分析可以证明没有其他任何东西可以指向它们,即,指向var的指针没有“转义”本地范围。就像编译器如何决定他们可以将var保留在非内联函数调用。)


那么没有"memory"一个人安全的volatile吗?没有

如果"memory"不使用闭环程序的显式输出操作数,它不会阻止asm语句进行优化。(如果没有“ = ...”操作数,则asm语句是隐式易失的)。

如果/当执行asm模板字符串时,必须假定具有内存缓冲区的非易失性asm语句可以在抽象机上的该点修改任何可访问的内存,但是编译器仍然可以自由进行转换,从而不会发生这种情况根本没有,或者比来源要少。(例如,如果在循环中更改的其他变量都是地址未转义该函数的所有本地变量,则将其从循环中吊起。)

volatile仍然假定asm语句是纯函数wrt。它的显式输入和输出,因此asm("..." : "=r"(out) : "r"(in) : "memory");如果循环在"in"每次迭代中都使用相同的循环,则可以将其吊出循环。(只有在循环变量是asm语句无法指向的所有局部变量的情况下,这种情况才会发生(转义分析,例如非内联函数调用)。否则,"memory"Clobber会阻止该重新排序。)

或完全优化掉(如果"out"可以优化所有使用),而不考虑语句周围的任何内存访问。如果省略,基于显式操作数进行决策volatile

这里没有很多用例的的"memory"撞无volatile; 您可以想象使用它来描述内部使用缓存来记忆结果的函数。编译器可以根据需要频繁或不频繁地运行它,而我们实际上并不关心内部缓存是否发生了突变。这是副作用,但不是有价值的副作用。


我假设CUDA内联汇编的语义与Clang / LLVM和GCC支持/实现的GNU C内联汇编的语义相同。从引号看来,确实是这种情况。我对CUDA并不了解,所以我上面说的一切都是基于GNU C内联汇编的,因为CUDA汇编看起来是相同的,如果我写错了,请更正我,例如asm,没有输出操作数的语句不是隐式的,volatile或者CUDA没有指针。

由于GNU C内联asm语法是为C设计的,后来又改用于CUDA,因此可以帮助您理解设计,以C的方式进行思考,包括指针和转义分析。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

相对于嵌入式系统,“易失性”关键字的意义是什么?

为什么[intro.execution] / 12将访问易失性glvalue视为副作用?

Java易失性和副作用

嵌入式 C - 易失性限定符在我的中断例程中无关紧要

嵌入式C-使用“易失性”声明一致性

为什么我们在嵌入式系统中内存有限?

为什么背景色在嵌入式网格中不起作用

ARM嵌入式ASM:退出系统调用,并从内存中读取值

嵌入式系统中的内存分配

为什么嵌入式linux(yocto)无法使用rootfs分区的全部内存?

在Camunda嵌入式表单中,如何指定绑定变量的作用域?

为什么在Java中无法读取易失性并写入字段成员?

为什么非易失性方法有效?

为什么易失性是较弱的同步形式?

将嵌入式程序分为内存中的多个部分

访问嵌入式内存中的HSQLDB实例

Maven中的嵌入式内存数据库

嵌入式mongo,不带端口(完全在内存中)

free()不释放嵌入式Linux中的内存。

在嵌入式Linux中检测低内存情况

在ARM嵌入式系统的内存中设置堆

嵌入式系统中的内存使用情况

嵌入式C中的动态内存分配

了解嵌入式 C 中的 I/O 内存位置

为什么我不能显示YouTube Live流中的嵌入式视频?

为什么Cocoapods抱怨嵌入式内容在构建设置中包含快速设置?

为什么在嵌入式设备中需要引导加载程序?

为什么嵌入式YouTube视频在Google Chrome浏览器中停止运行?

为什么在Google文档中复制表格不会复制嵌入式图形?