avx512
More than 3 years have passed since last update.

除算と言えば遅い命令のひとつですが、逆数(1/x) を求めるのはそんなに遅くないです。(y/x) の精度いらない時とかは、y * (1/x)にすると、除算よりも大分高速に近似値が求められます。

何故逆数は遅くないのか…は、よく知らないですが、変数一個になるのでテーブル引きできる + ニュートン法で求められるとかが効くのではないですかね…

SSE, AVXにも逆数命令はあって、スループットで1〜2サイクルあたり、4個、8個の 12bit 逆数が求められます。

逆数をニュートン法で求めるときは、1回反復するごとに、bit数が倍になるらしいので、12bitの逆数は、1回反復すると、24bitで、単精度分になります。

倍精度だと、ちょっと判断が難しくて、2回反復で48bit、 3回反復で96bitなので、精度捨てるか、時間捨てるかを迫られてる気がしますね。

AVX-512 では、逆数を28bit求める、vrcp28pd という命令が増えました。これなら倍精度でも1回反復するだけで52bit+オマケで4bit得られます。もう迷わなくてよいです。でもなんで26でなくて28bit…?丸め分も考慮してるの?よく知らないので詳しい人に聞いてください。

#include <immintrin.h>
#include <stdio.h>

double in[8] = {2,3,4,5, 6,7,8,9};
double out[8];

int
main()
{
    __m512d v = _mm512_loadu_pd(in);
    __m512d r = _mm512_rcp28_pd(v);
    _mm512_storeu_pd(out, r);

    for (int i=0; i<8; i++) {
        printf("%f\n", out[i]);
    }
}
 $ gcc -O2 a.c -mavx512er
 $ sde -knl -- ./a.out
0.500000
0.333333
0.250000
0.200000
0.166667
0.142857
0.125000
0.111111

AVX-512ER 拡張が必要です。Skylake, Cannonlake では動かず、KNLでは動きます。

また、SSE,AVX の12bit逆数は、倍精度版が無くて、倍精度で使う場合は単精度値から変換する必要があったのですが、AVX-512 では、14bit逆数を倍精度並びにしてくれる vrcp14pd が増えたので親切さが増してる感じがあります。さらに、14bitなら2回反復で52bit越えますね。vrcp14pd, vrcp14ps は、Skylakeでも使えます。

明日は @tanakmura が vexp2pd について書きます。

div
(ちなみにこれの答えはGoogle検索窓は電卓にも使える、でした)