2013-03-09 71 views
1

我必须完成以下使用MIC的512位向量单位:ZGEMM英特尔的MIC

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| 

我想的是,类似于英特尔已经提出了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 |

乘以上两者并使用类似于用于MIC的addsub_pd()。但似乎并没有相应的内在因素。

有关我如何实现这一目标的任何建议?

英特尔的MIC(至强融核)也有几个FMA内在像FMADD,fmsub,fnmadd,fnmsub应该借给自己这种情况,我有以下两种方法:

'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 

是否有更好的办法?这些方法的任何错误?

回答

1
tmp = _mm512_mul_pd(mo_t,in_r); 
tmp = _mm512_mask3_fmadd_pd(m0,in0,tmp,k1); with k1=10101010 
res = _mm512_mask3_fmsub_pd(m0,in0,tmp,k2); with k2=01010101 

为什么要使用_mm512_fnmadd_pd(v1,v2,v3)? 此内在函数的输出是(〜(v1 * v2)) - v3

+0

是不是_mm512_fnmsub_pd()? “在float64向量v1和float64向量v2之间执行逐元素乘法,然后否定结果并减去float64向量v3” – user1715122 2013-03-12 02:11:27

+0

除了上面的注释之外,是否可以从M形成m0和m0_t。我是考虑使用_mm512_swizzle_pd(),但我认为这不会起作用。有任何想法吗? – user1715122 2013-03-12 03:42:06

+0

permute + blend – user1584773 2013-03-13 08:57:35