ج - كيفية الوصول إلى عناصر المتجه باستخدام ملحق ناقلات GCC SSE

StackOverflow https://stackoverflow.com/questions/1771945

  •  21-09-2019
  •  | 
  •  

سؤال

عادةً ما أعمل مع ناقلات ثلاثية الأبعاد باستخدام الأنواع التالية:

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;
}

تدعم مجلس التعاون الخليجي هذه الطريقة. ولكن ... أولاً ، يعطيني 0.00000 نتيجة. ثانياً ، لا يمكنني الوصول إلى عناصر مثل هذه المتجهات. سؤالي هو: كيف يمكنني الوصول إلى عناصر من هذه المتجهات؟ أنا بحاجة إلى SMTH. مثل A [0] للوصول إلى عنصر X ، A [1] للوصول إلى عنصر Y ، إلخ.

ملاحظة: أقوم بتجميع هذا الرمز باستخدام:

gcc -msse testgcc.c -o testgcc
هل كانت مفيدة؟

المحلول

تتمثل الطريقة الآمنة والمصدرة للوصول إلى العناصر في اتحاد ، بدلاً من معاقبة نوع المؤشر ، والتي تخدع آليات الكشف عن الاسم المستعار للمترجم وقد تؤدي إلى رمز غير مستقر.

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]);

نصائح أخرى

لاحظ أن GCC 4.6 الآن يدعم المتجهات المشتركة:

في C يمكن الاشتراك في ناقلات C كما لو كان المتجه صفيفًا بنفس عدد العناصر ونوع الأساس. خارج الوصول إلى ملزمة استدعاء السلوك غير المحدد في وقت التشغيل. يمكن تمكين تحذيرات الوصول إلى الاشتراك في المتجه مع محاولات warray.

أنت تنسى أنك بحاجة إلى إعادة التفسير a كمجموعة من العوامات. الرمز التالي يعمل بشكل صحيح:

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;
}

ملاحظة: شكرًا على هذا السؤال ، لم أكن أعرف أن GCC لديها دعم SSE.

تحديث: فشل هذا الحل بمجرد أن يتم تحديد المصفوفات. الحل المقدم @drhirsh خالية من هذه المشكلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top