我想知道是否有一個SSE2/AVX2整數指令或指令(或內在)序列:C++ SSE2或AVX2內在灰度到ARGB轉換
給定一個的形式的8個字節的像素行:
A = {a, b, c, d, e, f, g, h}
是否有任何方式來加載在包含8個32位ARGB像素,使得初始灰度值被廣播到其它各2個字節的YMM寄存器這些像素對應的32位像素?結果應該是這樣的:(0是Alpha值)
B = {0aaa, 0bbb, 0ccc, 0ddd, 0eee, 0fff, 0ggg, 0hhh}
我在矢量擴展一個完整的初學者,所以我甚至不知道如何處理這一點,或者如果它是在所有可能的。
任何幫助,將不勝感激。謝謝!
UPDATE1
謝謝您的回答。我仍然有一個問題,但:
我把這個小例子放在一起,並編譯與VS2015在x64上。
int main()
{
unsigned char* pixels = (unsigned char*)_aligned_malloc(64, 32);
memset(pixels, 0, 64);
for (unsigned char i = 0; i < 8; i++)
pixels[i] = 0xaa + i;
__m128i grayscalePix = _mm_load_si128((const __m128i*)pixels);
__m256i rgba = _mm256_cvtepu8_epi32(grayscalePix);
__m256i mulOperand = _mm256_set1_epi32(0x00010101);
__m256i result = _mm256_mullo_epi32(rgba, mulOperand);
_aligned_free(pixels);
return 0;
}
的問題是,這樣做
__m256i rgba = mm256_cvtepu8_epi32(grayscalePix)
RGBA後只有第一四個雙設定。最後四個均爲0
英特爾開發者手冊說:
VPMOVZXBD YMM1,XMM2/M64
零擴展8封裝8位整數的低8個 字節XMM2的/ m64到8個打包的32位整數,在 ymm1。
我不確定這是意向行爲還是我仍然缺少某些東西。
謝謝。
您的代碼看起來正確。你確定你不只是測試錯誤?或者,由於結果未被使用,編譯器沒有優化它的全部或部分功能? [關於Godbolt](https://godbolt.org/g/TR15E9),我不得不使用'-O0'來使編譯器保持向量操作。即使'-Og'或'-O1'優化了除malloc/free之外的所有內容。嘗試將矢量存儲到'uint32_t'數組中,並用'printf'或者C++ ish來打印。 –
優化器不是一個問題,因爲我在調試模式下測試了這一點,但你仍然是正確的:)但顯然,VS調試器不會正確顯示_m256i值。它幾乎感覺像是在'_m128i'邊界截斷它們。另外,寄存器窗口也沒有太大的幫助。 在將矢量存儲到內存並做了一個'printf'後,一切看起來都很好,所以我想謝謝:) – redeye
哦,哇,當你不能相信調試器的時候,事情就變得很糟糕!當您使用結果時,調試器會更好嗎? –