ARM NEON: ما الفرق بين VLD4_F32 و VLD4Q_F32؟
-
26-09-2019 - |
سؤال
أنا لست في وضع يسمح لي بإحداث الفرق بين vld4_f32
و vld4q_f32
في تعليمات النيون الذراع.
بدأ الارتباك عندما رفعت مستويات الترميز الخاصة بي وبدأت في النظر في تعليمات التجميع بدلاً من الجوهارات الأقل إفادة.
السبب في أنني بحاجة إلى الاستخدام VLD4 تعليمات متغيرة هنا هي أنني أرغب في التقاط 4 float32_t
من كل المركز الرابع من صفيفتي الكبيرة.
ال vld4_f32
تبدو الجوهارات وتعليمات التجميع المقابلة هكذا (من هذا الرابط)
float32x2x4_t vld4_f32 (const float32_t *)
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0]
ال vld4q_f32
يبدو أن الجوهبات وتعليمات التجميع المقابلة لها مثل هذا
float32x4x4_t vld4q_f32 (const float32_t *)
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0]
حسنًا ، على مستوى الجوهارات الفرق الذي أراه هو نوع العودة, ، ولكن إذا نظرت إلى تعليمات التجميع وعدد السجلات ، فإن كلاهما يبدو وكأنه نفس الشيء. كيف سيعرف المترجم أو المجمع الفرق بين الاثنين؟
هل يمكن لشخص ما توضيح المزيد حول هذا الموضوع وشرح أيضًا كيف يمكنني تحقيق التحميل 4 float32_t القيم التي يتم وضعها في كل موقع ذاكرة رابع في سجل واحد؟
المحلول
نعم ، اكتشفت الفرق. لقد استخدمت CODESORCERY لمشاهدة محتويات التسجيل الفعلية لجميع تعليمات التحميل. الرابط الذي نشرته لا يعطي التفاصيل الكاملة على VLD4Q_F32.
حسنًا ، أولاً يأتي vld4_f32
, ، هذا الأحمال 4 د سجلات (مثل D16-19) لكل منها د يبلغ طول السجل 64 بت ، لذلك ستقوم هذه التعليمات بتحميل القيمة الثمانية الأولى المتشابكة بفاصل 4 كما هو موضح في الشكل أدناه.
في الحالة الثانية vld4q_f32
, ، هذا الأحمال 8 د السجلات (مثل D16-23) بدلاً من أربعة. لقارئ هذا حلقة الوصل, ، ليس من الواضح على الإطلاق أنه سيتم تحميل 8 سجلات. عندما نظرت إلى الرمز المتساقط لـ vld4qf32
, ، كان يستفيد من 8 D سجلات.
ستفعل هذه التعليمات بالفعل ما كنت آمل أن يفعله أي لتحميل 4 float32_t
القيم التي هي في الفاصل 4 كما هو موضح في الشكل أدناه.
نصائح أخرى
لقد قمت بتفكيك اثنين من الجوهرية ، ربما يساعد على شخص ما:
// C++
uint32x4x4_t r = vld4q_u32( ( uint32_t *) output );
// assembly
VLD4.32 {D16,D18,D20,D22}, [R0]!
VLD4.32 {D17,D19,D21,D23}, [R0]
// C++
uint32x2x4_t r = vld4_u32( ( uint32_t *) output );
// assembly
VLD4.32 {D20-D23}, [R0]