将unsigned chars转换为在程序集中浮动(以准备浮点向量计算)

时间:2010-10-21 21:11:21

标签: assembly sse2

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


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的其他每个字节都转换为float并将其存储到vVectX中?

谢谢!

2 个答案:

答案 0 :(得分:5)

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

清零

(2)从16位解包到32位(PUNPCKLWD,向量为零)

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

三条指示。

答案 1 :(得分:2)

超级老线程我意识到,但我自己在搜索代码来执行此操作。这是我的解决方案,我认为更简单:

#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

然而,基准测试显示它不会比在C中循环数组更快,并且启用了编译器优化。也许这种方法作为一堆AVX计算的初始阶段会更有用。