這篇就是系列文的最後一篇
"你也可以寫 SIMD 比寫網頁快" 的精神
不外乎就是 簡單 快速 有效
延續上兩篇在最後想要談的是搭配 clang + OpenCL vector 的進階使用方式
這裡只探討一個問題 : 使用那些基本的運算符號是否就能用上所有的 SIMD 指令?
很明顯的, 答案是不行(否則就不會有這篇啦 XDDDD)
但是如果你知道特定好用的 SIMD 指令該如何套用呢?
舉例來說 ARM NEON 有個特別的指令 VQDMULH
它的用途是將兩個 16/32bit 數值相乘後所產生的 32/64bit 數值, 取其高位的 16/32bit
以 code 表示的話:
int a, b, c;這指令對於 NEON 上實作常數的除法, 或是 fixed-point 的實作上很有幫助
...
c = sqdmulh(a, b);
// equal-to
int64 tmp;
tmp = a*b;
c = (int)(tmp>>32) ;
這時我們可以這麼做:
int4 va = {0, 1, 2, 3};上面的範例中 int32x4_t 為 NEON intrinsics 的 data type
int4 vb = {1, 2, 3, 4};
int4 vrab = vqdmulhq_s32(va, vb);
而基本的精神並不是什麼難以理解的事
僅是透過 pointer 作 NEON vector 與 OpenCL vector 的型別替換使用
而在之後要換回使用 OpenCL vector 可以透過一樣的方式轉回
接著我們可以透過 vec.s 觀察 clang code generation 的結果:
adr r0, .LCPI2_0在此為了確認這些暫存器間的關係, 可以參考 (ARMv7) NEON registers
...
vld1.64 {d16, d17}, [r0:128]
...
adr r0, .LCPI2_1
vld1.64 {d18, d19}, [r0:128]
vqdmulh.s32 q8, q9, q8
64b 的 (d16,d17) 即為 128b 的 q8
64b 的 (d18,d19) 即為 128b 的 q9
所以可以看到這樣的作法並沒有因此產生多餘的指令
是不是很簡單呢?
在此 "你也可以寫 SIMD 比寫網頁還快" 系列文告一段落
沒有留言:
張貼留言