fgo福袋が爆死 & やたら重かったので、バンディング低減のAVX512版を作ってみようとしたのだけど…
VC++2017の出力が謎…。
とりあえず、こんなコードがあったとします。
int main(int argc, char **argv) {
alignas(64) int16_t a[32];
alignas(64) int16_t b[32];
//適当に初期化
for (int i = 0; i < 32; i++) {
a[i] = rand() % INT16_MAX;
b[i] = rand() % INT16_MAX;
}
//ロード
__m512i z0 = _mm512_load_si512((__m512i *)(a));
__m512i z1 = _mm512_load_si512((__m512i *)(b));
//マスクを作るよ
__mmask32 mBlend = _mm512_cmpgt_epi16_mask(z0, z1);
//マスクを使うよ
__m512i z2 = _mm512_mask_mov_epi16(z0, mBlend, z1);
_mm512_storeu_si512((__m512i*)a, z2);
//最適化で全体が消されないようになんか出力しとく
printf("%d\n", a[0]);
return 0;
}
まあ、マスクを使いたいだけの簡単なコード…のはず。
これをVC++2017 (15.5.2)で32bitプログラムとしてコンパイルして、逆アセンブラのAVX512部分をみるとこんな感じになる…。
vmovdqa32 zmm0, ZMMWORD PTR _b$[esp+256]
vmovdqa32 zmm1, ZMMWORD PTR _a$[esp+256]
vpcmpw k1, zmm1, zmm0, 6
kmovd eax, k1
kmovd k1, eax
vmovdqu16 zmm1 {k1}, zmm0
vmovdqu32 zmm0, zmm1
vmovd eax, xmm0
この5行目と6行目はなんぞ? なぜ汎用レジスタに移して戻したし。
あと9行目も何がしたいのやら…。
一応、Function compile flags: /Ogtpyとなっているので、最適化はかかっているはず。
ちなみにg++(7.2.0) -O3 -mavx512f -mavx512bw -S -masm=intelだと、
vmovdqa64 zmm1, ZMMWORD PTR [esp+80]
mov DWORD PTR [esp], OFFSET FLAT:LC0
vmovdqa64 zmm0, ZMMWORD PTR [esp+16]
vpcmpgtw k1, zmm0, zmm1
vmovdqu16 zmm0{k1}, zmm1
vpextrw eax, xmm0, 0
やっぱいらないよねえ…。
決して間違った結果にはならないし、完璧に最適化しろというわけではないけど、さすがにもう少しうまくやってほしい…。それともなにか見落としているのだろうか?
うーん。どうしたものか。あまり気にしなくてもいいのかなあ…。
スポンサーサイト