9

通常、次のタイプを使用して 3D ベクトルを操作します。

typedef vec3_t float[3];

smth を使用してベクトルを初期化します。お気に入り:

vec3_t x_basis = {1.0, 0.0, 0.0};
vec3_t y_basis = {0.0, 1.0, 0.0};
vec3_t z_basis = {0.0, 0.0, 1.0};

smth を使用してそれらにアクセスします。お気に入り:

x_basis[X] * y_basis[X] + ...

ここで、SSE 命令を使用したベクトル演算が必要です。私は次のコードを持っています:

typedef float v4sf __attribute__ ((mode(V4SF)))
int main(void)
{
    v4sf   a,b,c;
    a = (v4sf){0.1f,0.2f,0.3f,0.4f};
    b = (v4sf){0.1f,0.2f,0.3f,0.4f};
    c = (v4sf){0.1f,0.2f,0.3f,0.4f};
    a = b + c;
    printf("a=%f \n", a);
    return 0;
}

GCC はそのような方法をサポートしています。しかし...まず、結果として0.00000が得られます。次に、そのようなベクトルの要素にアクセスできません。私の質問は、そのようなベクトルの要素にどのようにアクセスできますか? 私はスマートが必要です。X 要素にアクセスするには a[0]、Y 要素にアクセスするには a[1] など。

PS: 次を使用してこのコードをコンパイルします。

gcc -msse testgcc.c -o testgcc
4

3 に答える 3

17

要素にアクセスするための安全で推奨される方法は、ポインター型のパニングではなく共用体を使用することです。これは、コンパイラーのエイリアシング検出メカニズムを欺き、不安定なコードにつながる可能性があります。

union Vec4 {
    v4sf v;
    float e[4];
};

Vec4 vec;
vec.v = (v4sf){0.1f,0.2f,0.3f,0.4f};
printf("%f %f %f %f\n", vec.e[0], vec.e[1], vec.e[2], vec.e[3]);

于 2009-11-20T18:44:15.053 に答える
6

gcc 4.6 では添字付きベクトルがサポートされるようになったことに注意してください。

C では、ベクトルが同じ要素数と基本型を持つ配列であるかのように、ベクトルに添字を付けることができます。範囲外のアクセスは、実行時に未定義の動作を引き起こします。-Warray-bounds を使用すると、ベクトル サブスクリプションの境界外アクセスに対する警告を有効にすることができます。

于 2011-05-05T16:35:49.747 に答える
5

afloat の配列として再解釈する必要があることを忘れています。次のコードは正常に動作します。

int main(){
    v4sf a,b,c;
    a = (v4sf){0.1f,0.2f,0.3f,0.4f};
    b = (v4sf){0.1f,0.2f,0.3f,0.4f};
    c = (v4sf){0.1f,0.2f,0.3f,0.4f};
    a = b + c;
    float* pA = (float*) &a;
    printf("a=[%f %f %f %f]\n",pA[0], pA[1], pA[2], pA[3]);
    return 0;
}

PS: この質問をありがとう、gcc がそのような SSE をサポートしていることを知りませんでした。

更新:配列が整列されなくなると、このソリューションは失敗します。によって提供されるソリューションは@drhirsh、この問題から解放されています。

于 2009-11-20T17:38:23.563 に答える