AVX圖像算法優化系列二: 使用AVX2指令集加速查表算法。( 三 )


對于彩色的圖像 , 就要稍微復雜一些了,因為涉及到RGB格式的排布,同時考慮一些對齊問題,最友好的方式就是一次性處理8個像素,24個字節,這一部分留給有興趣的讀者自行研究 。
在我本機的CPU中測試呢,灰度版本的查找表大概有20%的提速,彩色版本的要稍微多一些,大概有30%左右 。
這些提速其實不太明顯,因為在整個過程中處理內存耗時較多,他并不是以計算為主要過程的算法 , 當我們某個算法中見也有查找時,并且為了計算查找表時 , 需要很多的數學運算去進行隱射的坐標計算時,這個時候這些隱射計算通常都是有浮點參與,或其他各種復雜的計算參與,這個時候用SIMD指令計算這些過程是能起到很大的加速作用的,在我們沒有AVX2之前,使用SSE實現時,到了進行查表時通常的做法都是把前通過SSE計算得到的坐標的_m128i元素的每個值使用_mm_extract_epi32(這個是內在的SSE指令 , 不是用其他偽指令拼合的)提取出每個坐標值,然后在使用_mm_set相關的函數把查找表的返回值拼接成一個行的SSE變量,以便進行后續的計算,比如下面的代碼:

AVX圖像算法優化系列二: 使用AVX2指令集加速查表算法。

文章插圖
這個時候使用AVX2的這個指令就方便了,如下所示:
AVX圖像算法優化系列二: 使用AVX2指令集加速查表算法。

文章插圖
注意到上面的Texture其實是個字節類型的數組 , 也就是一副圖像,對應的C代碼如下所示:
int SampleXF = IM_ClampI(ClipXF >> 16, 0, Width - 1);//試著拆分VX和VY的符號情況分開寫,減少ClampI的次數,結果似乎區別不是特別大,因此優化意義不大int SampleXB = IM_ClampI(ClipXB >> 16, 0, Width - 1);int SampleYF = IM_ClampI(ClipYF >> 16, 0, Height - 1);int SampleYB = IM_ClampI(ClipYB >> 16, 0, Height - 1);unsigned char *SampleF = Texture + (SampleYF * Stride + SampleXF);unsigned char *SampleB = Texture + (SampleYB * Stride + SampleXB);Sum += SampleF[0] + SampleB[0];可見這里實際上是對字節類型進行查表,所以這里最后的那個scale參數我們取的是1,即中間的偏移是以字節為單位的,但是這里其實隱含著一個問題 , 即如果我們取樣的是圖片最右下角的那個位置的像素,因為要從那個位置開始讀取四個字節的內存,除非圖像原始格式是BGRA的,否則 , 必然會讀取到超出圖像內存外的內存數據,這個在普通的C語言中 , 已改會彈出一個系統錯誤框,蹦的一下說訪問非法內存,但是我看用這個指令似乎目前還沒有遇到這個錯誤,哪怕認為的輸入一個會犯錯誤的坐標 。
如果是這樣的話,得到的一個好處就是對于那些圖像扭曲濾鏡、縮放圖像中哪些重新計算坐標的函數來說 , 不用臨時構建一副同樣數據的int類型圖了,而可以直接放心的使用這個函數了 。
最后說明一點 , 經過在其他一些機器上測試,似乎有些初代即使支持AVX2的CPU,使用這些函數后相應的算法的執行速度反而有下降的可能性,不知道為什么 。
在我提供的SIMD指令優化的DEMO中,在 Adjust-->Exposure菜單下可以看到使用C語言和使用AVX進行查表優化的功能,有興趣的作者可以自行比較下 。
AVX圖像算法優化系列二: 使用AVX2指令集加速查表算法。

文章插圖
很明顯,在這里SSE優化選項是無法使用的 。
本文可執行Demo下載地址:  https://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar,菜單中藍色字體顯示的部分為已經使用AVX加速的算法,如果您的硬件中不支持AVX2 , 可能這個DEMO你無法運行 。
如果想時刻關注本人的最新文章,也可關注公眾號:
AVX圖像算法優化系列二: 使用AVX2指令集加速查表算法。

文章插圖

推薦閱讀