4

SSE2 を使用して関数を最適化しようとしています。アセンブリ コードのデータをこの方法よりも適切に準備できるかどうか疑問に思っています。私のソース データは、pSrcData からの符号なし文字の束です。計算は float で行う必要があるため、この 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 の 1 バイトおきに float にキャストして vVectX に格納する、より迅速な方法はありますか?

ありがとう!

4

2 に答える 2

5

(1) 奇数バイトをゼロにするマスクとの AND ( PAND)

(2) 16 ビットから 32 ビットにアンパック (PUNPCKLWDゼロ ベクトルを使用)

(3) 32 ビット int を float に変換 ( CVTDQ2PS)

3 つの指示。

于 2010-10-21T21:54:44.263 に答える
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 計算の初期段階としてより役立つでしょう。

于 2017-09-21T05:40:39.113 に答える