2012-05-14 44 views
10

我有一個大像素處理函數,目前我正試圖使用​​內在函數進行優化。使用SIMD查找表

作爲一名SSE新手,我不確定如何處理涉及查找表的代碼部分。

基本上,我想向量化以下香草C++代碼:

//outside loop 
const float LUT_RATIO = 1000.0F; 

//in loop 
float v = ... //input value 
v = myLookupTable[static_cast<int>(v * LUT_RATIO)]; 

我試圖:

//outside loop 
const __m128 LUT_RATIO = _mm_set1_ps(1000.0F); 

//in loop 
__m128 v = _mm_set_ps(v1, v2, v3, v4); //input values 
__m128i vI = _mm_cvtps_epi32(_mm_mul_ps(v, LUT_RATIO)); //multiply and convert to integers 
v = ??? // how to get vI indices of myLookupTable? 

編輯:ildjarn讓那對我而言需要澄清的一點。我沒有試圖加快查找表代碼的速度,我只是試圖避免將寄存器存儲回專門用於查找的浮點數,因爲這部分內容夾在理論上可從SSE中受益的其他兩個部分之間。

+0

你認爲誰可以改進'myLookupTable [static_cast (v)* LUT_RATIO]'?這裏沒有進行計算,SSE爲什麼適用? – ildjarn

+2

@ildjarn我很確定我本身不能改進這部分,但我希望改進函數的其他部分,並避免在'__m128'和'float [4]之間來回移動的懲罰「我還必須矢量化這段代碼。 – Rotem

回答

12

如果您可以等到下一年,那麼英特爾的Haswell CPU將擁有AVX2,其中包含有關聚集負載的說明。這使您可以執行在一條指令中進行8個並行LUT查找(請參閱,例如,VGATHERDPS)。除此之外,你運氣不好,除非你的LUT很小(例如16個元素),在這種情況下你可以使用PSHUFB

+0

不幸的是我的LUT是10000個大元素。即使我要等待一個新的處理器,也要等上幾年,直到將Haswell指定爲最低cpu纔是合法的。 :) 謝謝(你的)信息。 – Rotem

+1

確定 - 如果您可以估算您的LUT,例如用多項式,那麼你仍然可以用SSE獲得勝利,否則恐怕你被標量代碼困住了。 –

+3

然後是標量代碼。從某種意義上說,這是一個好消息,我可以不再擔心這個部分,而是去尋找可能更加優化的部分。 – Rotem