PTX是一种中间表示,用于将C / C ++ GPU代码最终编译为单个微架构的SASS汇编语言。因此,在特定nVIDIA GPU微架构的实际指令集中,不应该被特定的孔/ gaffs / flukes /特性阻碍。
现在,PTX有一条指令来计算寄存器中前导零的数量:clz
。然而 - 它没有相应的ctz
指令,它会计算尾随零的数字。这些操作是“对称的”,人们当然希望在指令集中看到两者或两者都没有 - 特别是如果它是抽象的,并且不受特定硬件上可用的约束。流行的CPU架构已经存在多年。
奇怪的是,CUDA标头device_functions.h
声明了函数
* \brief Find the position of the least significant bit set to 1 in a 32 bit integer.
*
* [etc.]
*
* \return Returns a value between 0 and 32 inclusive representing the position of the first bit set.
* - __ffs(0) returns 0.
*/
__DEVICE_FUNCTIONS_DECL__ __device_builtin__ int __ffs(int x);
此功能:
clz
。__fls
- 找到最后一组。那么,为什么呢?为什么PTX中显然没有明显的指令,而且“假内置”几乎与标题中的相同?
答案 0 :(得分:2)
一般来说,与x86架构一样,CUDA和GPU架构的许多功能都是根据客户的反馈和需求而有机地积累起来的,而不是源于一些宏大的统一正交设计。
我个人将__ffs()
和__ffsll()
设备功能内在函数添加到CUDA。包含它们是因为它们代表了有用的位操作原语,并且完全匹配POSIX定义的ffs()
功能。
对于位操作,特别是对于定点操作和浮点仿真的实现,CLZ
是比CTZ
更重要的操作。最初,我在CUDA中实现了__clz()
和__clz()
作为短仿真序列。稍后添加了对CLZ
的硬件支持。我不是硬件架构团队的一员,但我有理由相信这些说明是根据客户反馈添加的。
PTX的主要目标之一是以抽象的形式公开底层硬件功能,因为每一代GPU都会对硬件的实际微体系结构进行重大更改。此虚拟ISA旨在作为本机指令集的瘦包装。原生GPU指令集非常小。例如,没有关于划分的说明。简单的硬件使芯片面积更小,核心数量更多。
为现有编译器提供实用目标(CUDA使用了Open64和LLVM工具链),虽然缺乏底层硬件支持,但PTX还增加了一些更高级别的操作。由于这代表了软件支持负担,因此可能没有动力添加更多此类操作。并非所有现有仿真都具有最高性能。在NVIDIA任职期间,我致力于优化最重要的 PTX操作的仿真序列。
CUDA用户可以通过错误报告机制提交增强请求(例如将CTZ
包含在PTX操作中)。