为什么CUDA PTX有clz但没有ctz,而CUDA标题有“假ffs”但没有fls?

时间:2017-04-23 09:39:24

标签: assembly cuda ptx

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);

此功能:

  • 与count-trailing-zeros具有几乎相同的语义 - 仅在全零输入上有所不同。
  • 转换为单个PTX指令,而是两个:按位否定,然后是clz
  • 也缺少其潜在对手__fls - 找到最后一组。

那么,为什么呢?为什么PTX中显然没有明显的指令,而且“假内置”几乎与标题中的相同?

1 个答案:

答案 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操作中)。