avx512
More than 3 years have passed since last update.

AVX-512 は、演算のオペランドがメモリの場合、スカラ値をブロードキャストできます。

つまり、条件によっては、_mm512_set1_ps( *mem ) は、コスト無しで実行できます。(今日のタイトルは命令が出ない!という意味でした(わかりづらい))

float x;
void
f(float *p, __m512 a)
{
    __m512 b = _mm512_add_ps(a, _mm512_set1_ps(x));

    _mm512_storeu_ps(out, b);
}

は、

f:
.LFB2214:
    .cfi_startproc
    vbroadcastss    x(%rip), %zmm1
    vaddps  %zmm1, %zmm0, %zmm0
    vmovups %zmm0, out(%rip)
    ret

このように、vaddps で broadcast していることが確認…でき…ない…?

本当なんです!信じてください!メモリをオペランドに取る場合はブロードキャストできるんです!お願いします!信じてください!!

llvm のtrunkで試したら出た。

f:                                      # @f
    .cfi_startproc
# BB#0:
    pushq   %rbp
.Ltmp0:
    .cfi_def_cfa_offset 16
.Ltmp1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
.Ltmp2:
    .cfi_def_cfa_register %rbp
    andq    $-64, %rsp
    subq    $64, %rsp
    vmovaps 16(%rbp), %zmm0
    vaddps  x(%rip){1to16}, %zmm0, %zmm0   ## {1to16}がついてる
    movw    $-1, %ax
    kmovw   %eax, %k1
    vmovups %zmm0, out(%rip) {%k1}
    movq    %rbp, %rsp
    popq    %rbp
    retq

1to16 が付いてるオペランドがブロードキャストされますね。しかしllvmさん無駄な命令出過ぎでは…(というかcalling conventionがGCCと一致してなくね?)

また、全てのオペランドがベクタレジスタに乗った512bit値、もしくはスカラ値の場合、追加の命令無しで演算の丸めを制御できます。

__m512
f(__m512 x)
{
    return _mm512_add_round_ps(x,x,_MM_FROUND_NO_EXC|_MM_FROUND_TO_NEAREST_INT);
}
f:
.LFB2211:
    .cfi_startproc
    vaddps  {rn-sae}, %zmm0, %zmm0, %zmm0
    ret

EVEXについて書く予定は無いと書いてましたが、それなりに調べてしまったので明日は@tanakmuraがEVEXについて書きます。