【问题标题】:zgemm on Intel's MICzgemm 在 Intel 的 MIC 上
【发布时间】:2013-03-09 00:42:55
【问题描述】:

我必须使用 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|

我想到的方法是,类似于英特尔为 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 (Xeon Phi) 也有几个 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

有没有更好的方法?这些方法有什么问题吗?

【问题讨论】:

    标签: vectorization sse matrix-multiplication avx intel-mic


    【解决方案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

    【讨论】:

    • 不就是_mm512_fnmsub_pd()吗? "在 float64 向量 v1 和 float64 向量 v2 之间执行逐个元素的乘法,然后将结果取反并减去 float64 向量 v3"
    • 除了上述注释之外,是否可以从 M 形成 m0 和 m0_t。我正在考虑使用 _mm512_swizzle_pd(),但我认为这不会起作用。有什么想法吗?
    • 实际上可以使用 _mm512_swizzle_pd() 的掩码变体
    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多