在汇编中将无符号字符转换为浮点数(为浮点向量计算做准备)

Posted

技术标签:

【中文标题】在汇编中将无符号字符转换为浮点数(为浮点向量计算做准备)【英文标题】:Converting unsigned chars to float in assembly (to prepare for float vector calculations) 【发布时间】:2010-10-21 21:11:20 【问题描述】:

我正在尝试使用 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】:

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

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

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

三个指令。

【讨论】:

【参考方案2】:

我意识到超级老线程,但我自己正在寻找代码来做到这一点。这是我的解决方案,我认为更简单:

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

#ifdef __AVX__
// Modified from http://***.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 计算的初始阶段会更有用。

【讨论】:

OP 只希望每个 other uint8_tfloat。对于 AVX2,最好的方法可能是 __m128i _mm_and_si128 然后是 _mm256_cvtepu16_epi32。或者,如果您稍后要打包回uint8_t,也许是一个 256b and,然后在转换为 FP 之前在通道内解压缩 lo/hi(反对零)从 16b 到 32b 整数元素。这样可以避免任何跨车道洗牌(如vpmovzx ymm),并且将避免需要反向洗牌再次打包。 是的,您希望在手动矢量化之前立即执行此操作。编译器可以自动矢量化简单的复制+转换循环。 谢谢彼得 - 我完全错过了

以上是关于在汇编中将无符号字符转换为浮点数(为浮点向量计算做准备)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

在 C++ 中将字符串转换为浮点数

如何在 Java 中将整数转换为浮点数?

如何在python中将数据帧中的符号转换为浮点数?

NEON 汇编代码,如何将 BYTE 转换为浮点数?

将(n个第一个字节)无符号字符指针转换为浮点数和双精度C++