アセンブリにフロートに署名されていないチャーを変換する(フロートベクトル計算の準備)
質問
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ビットINTをフロートに変換する(CVTDQ2PS
)
3つの指示。
他のヒント
私は気づいた超古いスレッドですが、私はこれを行うために自分でコードを探していました。これは私の解決策です。これはより簡単だと思います:
#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計算の束の初期段階としてより有用になるでしょう。
所属していません StackOverflow