无法在Cuda内核中使用__m128i

问题描述

我正在尝试使用cuda编译使用__m128i的简单程序,但是当我在Linux上使用nvcc(nvcc test.cu -o测试)进行编译时,得到"__m128i" is a vector,which is not supported in device code。 这是我要编译的程序

#include <stdio.h>
#include <emmintrin.h>

__global__ void hello(){
    printf("%d\n",threadIdx.x);
    __m128i x;

}
int main(){
   hello<<<3,3>>>();
}

当我输入nvcc --version时,我得到Cuda compilation tools,release 10.2,V10.2.89

我实际上在尝试使用CUDA实现某些cpp代码时遇到了更大的问题,而该cpp代码使用了__m128i,而我所展示的是我所面对的问题的简单版本,所以我想知道是否有一种方法可以在CUDA内核中使用__m128i或其他替代方法。谢谢

解决方法

我想知道在CUDA内核中是否有使用__m128i的方法...

没有。 CUDA的native 128 bit integer types具有与__m128i相同的对齐方式,但是不支持宿主向量类型。

或其他替代方法

如上所述,有16个字节对齐的类型可用于加载和存储数据,但NVIDIA GPU中没有本地的128位SIMD内在支持。存在的SIMD instructions限于32位类型。


CPU SIMD使用短向量(例如128位__m128i)完成。 GPU SIMD是跨线程完成的,通常不像__m128i CPU SIMD那样通过软件可见,您只需将其编写为标量代码即可。

使用__m128i手动矢量化的代码无法为GPU编译。如果它具有标量后备版本,请使用该版本,例如#undef __SSE2__

(32位块中的CUDA SIMD使您可以在每个GPU执行单元中的32位宽ALU中获得更多使用,如果您有狭窄的数据,例如成对的16位整数或4个8位整数。因此,如果您的SSE内部代码使用_mm_add_epi8,您可能仍会受益于CUDA中的手动矢量化,其4x 8位操作代替了16x 8位操作。)