假設我想添加兩個緩衝區並存儲結果。兩個緩衝區已分配16byte對齊。我發現了兩個例子如何做到這一點。SSE:_mm_load/store與使用直接指針訪問之間的區別
第一個是使用_mm_load從緩衝區讀取數據到一個SSE寄存器,執行添加操作並將其存儲回結果寄存器。直到現在,我會這樣做。
void _add(uint16_t * dst, uint16_t const * src, size_t n)
{
for(uint16_t const * end(dst + n); dst != end; dst+=8, src+=8)
{
__m128i _s = _mm_load_si128((__m128i*) src);
__m128i _d = _mm_load_si128((__m128i*) dst);
_d = _mm_add_epi16(_d, _s);
_mm_store_si128((__m128i*) dst, _d);
}
}
第二個例子只是在沒有加載/存儲操作的情況下直接在內存地址上進行加操作。兩條縫工作正常。
void _add(uint16_t * dst, uint16_t const * src, size_t n)
{
for(uint16_t const * end(dst + n); dst != end; dst+=8, src+=8)
{
*(__m128i*) dst = _mm_add_epi16(*(__m128i*) dst, *(__m128i*) src);
}
}
所以,問題是如果該第二示例是正確的,或者可以具有任何副作用以及何時使用加載/存儲是強制性的。
謝謝。
有沒有人知道任何「官方」文件在深層解釋這一點?我使用了「英特爾®C++內部函數參考」,但發現它不能清楚地回答我的問題。 – Peter
'load' /'loadu'內在函數的主要目的是將對齊信息傳遞給編譯器。並且(對於float/double),可以從'float *'輸入到'__m128'或'double *'到'__m128d'。對於整數,你必須自己施放。 (但固定AVX512,其中整數加載/存儲內部函數採取'void *'參數) –