我想你想要的是這樣的:
double i0[2];
double i1[2];
__m128d x1 = _mm_load_pd(i0);
__m128d x2 = _mm_load_pd(i1);
__m128d sum = _mm_add_pd(x1, x2);
// do whatever you want to with "sum" now
當你做一個_mm_load_pd
,它把第一雙入冊和第二的低64位到上16位。因此,在上述負荷後,x1
保留兩個double
值i0[0]
和i0[1]
(以及類似的x2
)。對_mm_add_pd
的調用垂直添加了x1
和x2
中的相應元素,因此在添加之後,sum
將i0[0] + i1[0]
保留在其較低的64位中,將i0[1] + i1[1]
保留在其較高的64位中。
編輯:我應該指出,有使用_mm_load_pd
代替_mm_load_ps
沒有好處。如函數名稱所示,pd
類顯式加載兩個壓縮雙精度,並且ps
版加載四個壓縮單精度浮點數。由於這些都是純位移內存,並且都使用SSE浮點單元,所以使用_mm_load_ps
加載double
數據沒有任何損失。而且,_mm_load_ps
還有一個好處:它的指令編碼比_mm_load_pd
短一個字節,所以它從指令高速緩存意義上講效率更高(可能還有指令解碼;我不是現代x86處理器所有複雜性的專家)。使用_mm_load_ps
上面的代碼看起來像:
double i0[2];
double i1[2];
__m128d x1 = (__m128d) _mm_load_ps((float *) i0);
__m128d x2 = (__m128d) _mm_load_ps((float *) i1);
__m128d sum = _mm_add_pd(x1, x2);
// do whatever you want to with "sum" now
沒有被蒙上暗示的功能;它只是讓編譯器重新解釋SSE寄存器的內容爲保持雙精度而不是浮點數,以便它可以傳遞到雙精度算術函數_mm_add_pd
。
你當然可以使用'_mm_load_ps',但風險在其上設計了這樣一種方式的假設未來處理器性能的下降,有單間域旁路處罰和雙精度浮點運算。我知道沒有這樣的處理器的計劃,但這並不是說永遠不會實施;這就是爲什麼有不同的加載操作。誠然,這是一個遙遠的可能性,但爲什麼冒這個險呢? – 2012-02-13 15:32:51
我同意未來的處理器存在性能下降的風險。我建議人們考慮(即衡量)通過在特定應用的基礎上使用「MOVPS」而不是「MOVPD」來獲得任何性能優勢。如果今天使用它是有好處的,並且沒有跡象表明即將到來的架構會有這樣的懲罰,我會這樣做。像這樣的負載可以很容易地被抽象化,以允許將來自動切換到不同的實現。 – 2012-02-13 16:41:58