次のコード スニペットがどのように機能するかを理解しようとしています。このプログラムは、SIMD ベクトル命令 (Intel SSE) を使用して、4 つの float の絶対値を計算します (基本的に、ベクトル化された「fabs()」関数)。
スニペットは次のとおりです。
#include <iostream>
#include "xmmintrin.h"
template <typename T>
struct alignas(16) sse_t
{
T data[16/sizeof(T)];
};
int main()
{
sse_t<float> x;
x.data[0] = -4.;
x.data[1] = -20.;
x.data[2] = 15.;
x.data[3] = -143.;
__m128 a = _mm_set_ps1(-0.0); // ???
__m128 xv = _mm_load_ps(x.data);
xv = _mm_andnot_ps(a,xv); // <-- Computes absolute value
sse_t<float> result;
_mm_store_ps(result.data, xv);
std::cout << "x[0]: " << result.data[0] << std::endl;
std::cout << "x[1]: " << result.data[1] << std::endl;
std::cout << "x[2]: " << result.data[2] << std::endl;
std::cout << "x[3]: " << result.data[3] << std::endl;
}
プログラムを自分で実行してテストしたので、動作することがわかりました。g++ 4.8.2 でコンパイルすると、結果は次のようになります。
x[0]: 4
x[1]: 20
x[2]: 15
x[3]: 143
3 つの (関連する) 質問が私を困惑させます。
まず、ビットごとの関数を取得して float に適用することはどのように可能でしょうか? バニラ C++ でこれを試してみると、これは整数型に対してのみ機能することがわかります (これは理にかなっています)。
しかし、第二に、さらに重要なことは、どのように機能するのかということです。NOT と AND を取ることは、ここでどのように役立ちますか? 整数型を使用して Python でこれを試すと、期待どおりの結果が得られます。任意の整数 AND -1 (これは 0 ではありません) は、単純にその数値を返しますが、符号は変更しません。では、ここでどのように機能しますか?
第 3 に、NAND 演算に使用する float の値 (3 つの ??? でマーク) を -0.0 から 0.0 に変更すると、プログラムが絶対値を返さなくなることに気付きました。しかし、-0.0 はどのように存在し、どのように役立つのでしょうか?
参考文献: