アカウント名:
パスワード:
32bit float 精度ですけど、AMDの今は亡き3DNow!には除算命令はなく、逆数算出とかけ算を組み合わせる [nifty.com]ことになっていて、さらに逆数算出は・テーブル引きの低精度逆数算出命令・ニュートンラフソン法による精度向上命令の二命令4クロックで割り算ができていました。(平方根も同様で、1/√x の低精度算出と精度向上の2命令 [nifty.com])
低精度で十分な用途なら、テーブル引きだけにして高速化も可能というなかなか便利なものだったんですが、結局IntelのSSEに負けて、最新世代ではサポートされなくなっちゃいました [fc2.com]ね。
SSEを先に使っていて3DNow!は知らなかったので、後で調べてみて、Intelがぱくったのを知ったり。
#SSEで近似値を使う場合は、こんな感じかな#要素数4でも処理速度は同じinline float newton_divide(float a, float b){ __m128 value_a; __m128 value_b; __m128 tmp_0; __m128 tmp_1; __m128 tmp_2; __m128 tmp_3; __m128 two;
two.m128_f32[0] = 2.0f; value_a.m128_f32[0] = a; value_b.m128_f32[0] = b; tmp_0 = _mm_rcp_ss(value_b); tmp_1 = _mm_sub_ss(two, _mm_mul_ss(value_b, tmp_0)); tmp_2 = _mm_mul_ss(tmp_1, tmp_0); tmp_3 = _mm_mul_ss(value_a, tmp_2);
return tmp_3.m128_f32[0];}
inline float newton_sqrt(float a){ __m128 value_a; __m128 tmp_0; __m128 tmp_1; __m128 tmp_2; __m128 tmp_3; __m128 tmp_4; __m128 two; __m128 three; __m128 invTwo;
two.m128_f32[0] = 2.0f; three.m128_f32[0] = 3.0f; invTwo.m128_f32[0] = 0.5f; value_a.m128_f32[0] = a; tmp_0 = _mm_rsqrt_ss(value_a); tmp_1 = _mm_mul_ss(tmp_0, tmp_0); tmp_2 = _mm_mul_ss(_mm_sub_ss(three, _mm_mul_ss(value_a, tmp_1)), invTwo); tmp_3 = _mm_mul_ss(tmp_2, tmp_0); tmp_4 = _mm_mul_ss(tmp_3, value_a);
return tmp_4.m128_f32[0];}
余計なモノが付いているけど、キニシナイ。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲはアレゲを呼ぶ -- ある傍観者
AMD 3DNow! (スコア:1)
32bit float 精度ですけど、AMDの今は亡き3DNow!には除算命令はなく、逆数算出とかけ算を組み合わせる [nifty.com]ことになっていて、さらに逆数算出は
・テーブル引きの低精度逆数算出命令
・ニュートンラフソン法による精度向上命令
の二命令4クロックで割り算ができていました。(平方根も同様で、1/√x の低精度算出と精度向上の2命令 [nifty.com])
低精度で十分な用途なら、テーブル引きだけにして高速化も可能というなかなか便利なものだったんですが、結局IntelのSSEに負けて、最新世代ではサポートされなくなっちゃいました [fc2.com]ね。
Re:AMD 3DNow! (スコア:2)
SSEを先に使っていて3DNow!は知らなかったので、後で調べてみて、Intelがぱくったのを知ったり。
#SSEで近似値を使う場合は、こんな感じかな
#要素数4でも処理速度は同じ
inline float newton_divide(float a, float b)
{
__m128 value_a;
__m128 value_b;
__m128 tmp_0;
__m128 tmp_1;
__m128 tmp_2;
__m128 tmp_3;
__m128 two;
two.m128_f32[0] = 2.0f;
value_a.m128_f32[0] = a;
value_b.m128_f32[0] = b;
tmp_0 = _mm_rcp_ss(value_b);
tmp_1 = _mm_sub_ss(two, _mm_mul_ss(value_b, tmp_0));
tmp_2 = _mm_mul_ss(tmp_1, tmp_0);
tmp_3 = _mm_mul_ss(value_a, tmp_2);
return tmp_3.m128_f32[0];
}
inline float newton_sqrt(float a)
{
__m128 value_a;
__m128 tmp_0;
__m128 tmp_1;
__m128 tmp_2;
__m128 tmp_3;
__m128 tmp_4;
__m128 two;
__m128 three;
__m128 invTwo;
two.m128_f32[0] = 2.0f;
three.m128_f32[0] = 3.0f;
invTwo.m128_f32[0] = 0.5f;
value_a.m128_f32[0] = a;
tmp_0 = _mm_rsqrt_ss(value_a);
tmp_1 = _mm_mul_ss(tmp_0, tmp_0);
tmp_2 = _mm_mul_ss(_mm_sub_ss(three, _mm_mul_ss(value_a, tmp_1)), invTwo);
tmp_3 = _mm_mul_ss(tmp_2, tmp_0);
tmp_4 = _mm_mul_ss(tmp_3, value_a);
return tmp_4.m128_f32[0];
}
Re:AMD 3DNow! (スコア:2)
余計なモノが付いているけど、キニシナイ。