我对定义half
的正确方法感到困惑 - 设备上的精确数据分配。例如,如果我希望在设备内存中有一个half
数组,是否应该这样分配?
__device__ half array[32];
或者它会将实际的设备内存使用量与float
的数组相同,因为每个half
都存储在未使用的位之前吗? (就像bool
必须占用整个存储器地址,而不仅仅是1位)是否正确分配如下方式?
__device__ half2 array[16];
如果两个net都分配了相同的字节数,那么half2
的重点是什么?
答案 0 :(得分:3)
两个声明都占用相同的空间。从代码正确性的角度来看,这两种方法都是可用的。
half2
应该是首选,至少有两个原因:
在进行warp-wide加载时,每个线程一个half2
将比每个线程half
更高效地加载(或存储)。
addition and multiplication之类的某些操作只能在{{1}上完成支持此类操作(cc5.3和cc6.1及更高版本)的体系结构上实现完全(即最高)吞吐量键入(忽略此讨论中的Volta tensorCore操作)。
在其他方面,关于是否使用其中一个或另一个的决定可能等同于询问任何其他矢量类型,例如half2
与int
。我不打算在此处对使用矢量类型的动机进行完整的总结。
给出的两个示例的底层内存存储模式是相同的,因此通常,指向int2
的正确对齐的指针应该是可转换的(例如,在正确/交替的索引边界上){{1}同样,half
指针应安全地转换为half2
。
即使您选择使用half2
,在某些情况下使用half
可能是适当的或不可避免的,例如,如果您需要修改单个数量,或者例如certain CUBLAS function calls }。在这种情况下,至少使用最新版本的CUDA,可以将half2
转换为half
(反之亦然),就像使用任何其他矢量类型一样:
half2
并且如前所述,half
指针可以安全地转换为__device__ half2 array[16];
...
half2 myval = array[0];
half first = myval.x;
half second = myval.y;
:
half2
This有些相关的问题也可能会引起人们的兴趣。