Assembly 将程序集中的无符号字符转换为浮点(为浮点向量计算做准备)

Assembly 将程序集中的无符号字符转换为浮点(为浮点向量计算做准备),assembly,sse2,Assembly,Sse2,我正在尝试使用SSE2优化函数。我想知道我是否可以为我的汇编代码准备比这种方式更好的数据。我的源数据是pSrcData中的一组未签名字符。我将它复制到这个浮点数组中,因为我的计算需要在浮点中进行 unsigned char *pSrcData = GetSourceDataPointer(); __declspec(align(16)) float vVectX[4]; vVectX[0] = (float)pSrcData[0]; vVectX[1] = (float)pSrcData[

我正在尝试使用SSE2优化函数。我想知道我是否可以为我的汇编代码准备比这种方式更好的数据。我的源数据是pSrcData中的一组未签名字符。我将它复制到这个浮点数组中,因为我的计算需要在浮点中进行


unsigned char *pSrcData = GetSourceDataPointer();

__declspec(align(16)) float vVectX[4];

vVectX[0] = (float)pSrcData[0];
vVectX[1] = (float)pSrcData[2];
vVectX[2] = (float)pSrcData[4];
vVectX[3] = (float)pSrcData[6];

__asm 
{
     movaps xmm0, [vVectX]
     [...]  // do some floating point calculations on float vectors using addps, mulps, etc
}

有没有一种更快的方法让我将pSrcData的每一个字节转换成一个浮点并存储到vVectX中

谢谢

(1)并使用掩码将奇数字节归零(
PAND

(2) 从16位解压到32位(
PUNPCKLWD
带零向量)

(3) 将32位整数转换为浮点(
CVTDQ2PS


三条指令。

我意识到这是一条非常古老的线索,但我一直在自己寻找代码来实现这一点。这是我的解决方案,我认为更简单:

#include <immintrin.h>
#include <stdint.h>

#ifdef __AVX__
// Modified from http://stackoverflow.com/questions/16031149/speedup-a-short-to-float-cast
// Convert unsigned 8 bit integer to  float. Length must be multiple of 8
int  avxu8tof32(uint8_t *src, float *dest, int length) {
  int i;

  for (i=0; i<length; i+= 8) {

    //  Load 8 8-bit int into the low half of a 128 register
    __m128i v = _mm_loadl_epi64 ((__m128i const*)(src+i));

    //  Convert to 32-bit integers
    __m256i v32 = _mm256_cvtepu8_epi32(v);

    //  Convert to float
    __m256 vf = _mm256_cvtepi32_ps (v32);

    //  Store
    _mm256_store_ps(dest + i,vf);
  }
  return(0);
}
#endif
#包括
#包括
#ifdef__AVX__
//修改自http://stackoverflow.com/questions/16031149/speedup-a-short-to-float-cast
//将无符号8位整数转换为浮点。长度必须是8的倍数
int avxu8tof32(uint8_t*src,float*dest,int-length){
int i;

对于(i=0;它只希望每隔一个
uint8\u t
作为一个
float
。对于AVX2,最好的可能是
\u m128i
\u mm\u和
,然后
\u mm256\u cvtepu16\u epi32
。或者如果以后要打包回
uint8\u t
,可能是256b
,然后解包(相对于零)在车道中,在转换为FP之前从16b到32b整数元素。这避免了任何车道交叉混乱(如
vpmovzx ymm
),并将避免再次打包时需要反向洗牌。是的,您希望在手动矢量化某些内容之前立即执行此操作。编译器可以自动矢量化简单的复制+转换循环。谢谢Peter-我完全忽略了这一点