Преобразование символов без знака в число с плавающей точкой в ​​сборке (для подготовки к вычислениям вектора с плавающей точкой) - PullRequest
4 голосов
/ 22 октября 2010

Я пытаюсь оптимизировать функцию, используя 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?

Спасибо!

Ответы [ 2 ]

5 голосов
/ 22 октября 2010

(1) И с маской для обнуления нечетных байтов (PAND)

(2) Распаковка от 16 до 32 бит (PUNPCKLWD с нулевым вектором)

(3) Преобразовать 32-битные целые числа в числа с плавающей запятой (CVTDQ2PS)

Три инструкции.

2 голосов
/ 21 сентября 2017

Я понимаю, что это очень старая тема, но я сам искал для этого код.Это мое решение, которое я считаю более простым:

#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.

...