MIC の 512 ビット ベクトル ユニットを使用して、次のことを達成する必要があります。
M->|b4|a4|b3|a3|b2|a2|b1|a1|
I->|d4|c4|d3|c3|d2|c2|d1|c1|
O-> O + |a4d4+b4c4|a4c4-b4d4|a3d3+b3c3|a3c3-b3d3|a2d2+b2c2|a2c2-b2d2|a1d1+b1c1|a1c1-b1d1|
私が考えた方法は、Intel が SSE に対して提案したものと同様で、AVX でも機能します。
_mm512_swizzle_pd()
関数を使用して以下を形成します。
m0 = |a4|a4|a3|a3|a2|a2|a1|a1| および m0_t = |b4|b4|b3|b3|b2|b2|b1|b1| in0 = |d4|c4|d3|c3|d2|c2|d1|c1| in0_r = |c4|d4|c3|d3|c2|d2|c1|d1|
上記の 2 つを乗算し、MIC の addsub_pd() に似たものを使用します。しかし、対応する組み込み関数はないようです。
これを達成する方法について何か提案はありますか?
Intel の MIC (Xeon Phi) には、fmadd、fmsub、fnmadd、fnmsub などのいくつかの FMA 組み込み関数もあり、この状況に役立つはずであり、次の 2 つのアプローチがあります。
'O' is the output register
Approach 1 :
1. _mm512_fmadd_pd(m0,in0,O);
2. Explicitly set m0_t using _mm512_set_pd() to make it: |b4|-b4|b3|-b3|b3|-b3|b1|-b1|
3. _mm512_fmadd_pd(m0_r,in0_r,O);
Approach 2:
1. _mm512_fmadd_pd(m0,in0,O);
2. _mm512_mask_fmadd_pd(m0_r,k1,in0_r,O); with k1=10101010
3. _mm512_mask_fnmadd_pd(m0_r,k2,in0_r,O); with k2=01010101
より良いアプローチはありますか?これらのアプローチの欠点はありますか?