سؤال

هل هناك أي فرق بين الجوهبات المنطقية SSE لأنواع مختلفة؟ على سبيل المثال ، إذا أخذنا أو عملنا ، فهناك ثلاثة جوادات: _mm_or_ps ، _mm_or_pd و _mm_or_si128 وكلها تفعل الشيء نفسه: حساب bitwise أو من معاملاتهم. أسئلتي:

  1. هل هناك أي فرق بين استخدام واحد أو آخر جوهري (مع صب النوع المناسب). ألن يكون هناك أي تكاليف خفية مثل التنفيذ الأطول في موقف محدد؟

  2. هذه الخرائط الجوهرية إلى ثلاث تعليمات X86 مختلفة (POR ، ORPs ، ORPD). هل لدى أي شخص أي أفكار لماذا تضيع Intel مساحة الرمز البسيط الثمين للعديد من التعليمات التي تفعل الشيء نفسه؟

هل كانت مفيدة؟

المحلول

أعتقد أن الثلاثة متماثلون بشكل فعال ، أي 128 بت العمليات البت. سبب وجود أشكال مختلفة على الأرجح تاريخية ، لكنني لست متأكدًا. أعتقد أنه المستطاع قد يكون هناك بعض السلوك الإضافي في إصدارات النقطة العائمة ، على سبيل المثال عندما يكون هناك nans ، ولكن هذا تخمين خالص. بالنسبة للمدخلات العادية ، يبدو أن الإرشادات قابلة للتبديل ، على سبيل المثال

#include <stdio.h>
#include <emmintrin.h>
#include <pmmintrin.h>
#include <xmmintrin.h>

int main(void)
{
    __m128i a = _mm_set1_epi32(1);
    __m128i b = _mm_set1_epi32(2);
    __m128i c = _mm_or_si128(a, b);

    __m128 x = _mm_set1_ps(1.25f);
    __m128 y = _mm_set1_ps(1.5f);
    __m128 z = _mm_or_ps(x, y);

    printf("a = %vld, b = %vld, c = %vld\n", a, b, c);
    printf("x = %vf, y = %vf, z = %vf\n", x, y, z);

    c = (__m128i)_mm_or_ps((__m128)a, (__m128)b);
    z = (__m128)_mm_or_si128((__m128i)x, (__m128i)y);

    printf("a = %vld, b = %vld, c = %vld\n", a, b, c);
    printf("x = %vf, y = %vf, z = %vf\n", x, y, z);

    return 0;
}

$ gcc -Wall -msse3 por.c -o por

$ ./por

a = 1 1 1 1, b = 2 2 2 2, c = 3 3 3 3
x = 1.250000 1.250000 1.250000 1.250000, y = 1.500000 1.500000 1.500000 1.500000, z = 1.750000 1.750000 1.750000 1.750000
a = 1 1 1 1, b = 2 2 2 2, c = 3 3 3 3
x = 1.250000 1.250000 1.250000 1.250000, y = 1.500000 1.500000 1.500000 1.500000, z = 1.750000 1.750000 1.750000 1.750000

نصائح أخرى

  1. هل هناك أي فرق بين استخدام واحد أو آخر جوهري (مع صب النوع المناسب). ألن يكون هناك أي تكاليف خفية مثل التنفيذ الأطول في موقف محدد؟

نعم ، يمكن أن يكون هناك أسباب أداء لاختيار واحد مقابل الآخر.

1: في بعض الأحيان ، هناك دورة إضافية أو اثنتين من الكمون (تأخير إعادة التوجيه) إذا كان إخراج وحدة تنفيذ عدد صحيح يحتاج إلى توجيه إلى إدخال وحدة تنفيذ FP ، أو العكس. يتطلب الأمر الكثير من الأسلاك لنقل 128B من البيانات إلى أي من الوجهات المحتملة العديدة ، لذلك يتعين على مصممي وحدة المعالجة المركزية أن يصنعوا مقايضات ، مثل امتلاك مسار مباشر فقط من كل إخراج FP إلى كل إدخال FP ، وليس لجميع المدخلات الممكنة.

نرى هذا الجواب, ، أو وثيقة بنية Agner Fog's Microarchitecture لتجاوز الأداء. ابحث عن "تأخير بيانات البيانات على Nehalem" في Doc Agner ؛ لديها بعض الأمثلة العملية الجيدة والمناقشة. لديه قسم على كل microarch الذي حلله.

ومع ذلك ، فإن التأخير في تمرير البيانات بين المجالات المختلفة أو أنواع مختلفة من السجلات أصغر على جسر Sandy و Ivy Bridge مقارنةً بـ Nehalem ، وغالبًا ما تكون صفرًا. - وثيقة القوس المتكافئ في أجنر الضباب

تذكر أن الكمون لا يهم ما إذا لم يكن على الطريق الحرج للرمز الخاص بك. استخدام pshufd بدلاً من movaps + shufps يمكن أن يكون الفوز إذا كانت إنتاجية UOP هي عنق الزجاجة ، بدلاً من زمن انتقال مسارك الحرج.

2: ال ...ps يأخذ الإصدار 1 بايت من الكود من الاثنين الآخرين. سيؤدي ذلك إلى مواءمة الإرشادات التالية بشكل مختلف ، والتي يمكن أن تهم خطوط التخزين المؤقت و/أو UOP.

3: يمكن لوحدة المعالجة المركزية الأخيرة لـ Intel تشغيل إصدارات FP على Port5.

  • ميروم (Core2) و Penryn: orps يمكن تشغيل على P0/P1/P5 ، ولكن المجال عدد صحيح فقط. من المفترض أن جميع الإصدارات الثلاثة فك تشفيرها في نفس UOP بالضبط. لذلك يحدث تأخير إعادة التوجيه عبر المجال. (AMD CPUS قم بذلك أيضًا: تعليمات FP bitwise تعمل في مجال IVEC.)

  • Nehalem / Sandybridge / IVB / Haswell / Broadwell: por يمكن تشغيل على p0/p1/p5 ، ولكن orps يمكن تشغيل فقط على port5. هناك حاجة أيضًا إلى P5 من قبل عمليات الاختطاف ، ولكن وحدات FMA و FP Add و FP MUL موجودة على المنافذ 0/1.

  • سكليك: por و orps كلاهما لديه 3-كل دورة الإنتاجية. المعلومات حول إعادة توجيه التأخير غير متوفرة بعد.

لاحظ أنه على SNB/IVB (AVX ولكن ليس AVX2) ، يحتاج P5 فقط إلى التعامل مع 256B OPS المنطقية ، مثل vpor ymm, ymm يتطلب AVX2. ربما لم يكن هذا هو سبب التغيير ، لأن نهالم فعل هذا.

كيف تختار بحكمة:

إذا كان بإمكان إنتاجية OP المنطقية على Port5 عنق الزجاجة ، فاستخدم إصدارات عدد صحيح ، حتى على بيانات FP. هذا صحيح بشكل خاص إذا كنت ترغب في استخدام خلط عدد صحيح أو تعليمات أخرى لحركة البيانات.

تستخدم CPU AMD دائمًا مجال Integer للمنطق ، لذلك إذا كان لديك أشياء متعددة في مجال عدد صحيح يمكنك القيام بها ، فقم بها جميعًا مرة واحدة لتقليل الرحلات المستديرة بين المجالات. سوف يتم إزالة الأشياء الأقصر من إزالة الأشياء من المخزن المؤقت بشكل أسرع ، حتى لو لم تكن سلسلة DEP هي عنق الزجاجة للرمز الخاص بك.

إذا كنت ترغب فقط في تعيين/مسح/قلب قليلاً في متجهات FP بين تعليمات FP و MUL ، استخدم ...ps المنطقات ، حتى في بيانات الدقة المزدوجة ، لأن FP الفردي والمزدوج هي نفس المجال في كل وحدة المعالجة المركزية في الوجود ، و ...ps الإصدارات هي واحدة بايت أقصر.

هناك أسباب عملية / عامل إنسان لاستخدام ...pd الإصدارات ، والتي سوف تفوق في كثير من الأحيان توفير 1 بايت من الكود. قابلية قراءة الكود الخاص بك من قبل البشر الآخرين هي عامل: سوف يتساءلون عن سبب تعاملك مع بياناتك كفردي عندما تتضاعف بالفعل. esp. مع الجوهارات C/C ++ ، تتناثر الكود الخاص بك مع يلقي بين __mm256 و __mm256d لا يستحق كل هذا العناء. إذا كان ضبط مستوى محاذاة insn ، فاكتب في ASM مباشرة ، وليس الجوهارات! (إن وجود تعليمات بايت واحد أطول قد يتوافق بشكل أفضل مع كثافة خط ذاكرة التخزين المؤقت UOP و/أو فك التشفير.)

لبيانات عدد صحيح ، استخدم إصدارات عدد صحيح. لا يستحق حفظ بايت تعليمات واحد إلى الالتفاف ، وغالبًا ما يحتفظ رمز الصدفة بشكل كامل بالضربات. بالنسبة إلى Haswell ، أصبحت العديد من إرشادات خلط / إدراج / استخراج / حزمة / إلغاء التعبير P5 فقط ، بدلاً من P1 / P5 لـ SNB / IVB.

  1. هذه الخرائط الجوهرية إلى ثلاث تعليمات مختلفة x86 (por, orps, orpd). هل لدى أي شخص أي أفكار لماذا تضيع Intel مساحة الرمز البسيط الثمين للعديد من التعليمات التي تفعل الشيء نفسه؟

إذا نظرت إلى تاريخ مجموعات التعليمات هذه ، يمكنك رؤية كيف وصلنا إلى هنا.

por  (MMX):     0F EB /r
orps (SSE):     0F 56 /r
orpd (SSE2): 66 0F 56 /r
por  (SSE2): 66 0F EB /r

كان MMX موجودًا قبل SSE ، لذلك يبدو وكأنه رموز opcs for SSE (...ps) تم اختيار التعليمات من نفس الشيء 0F xx الفضاء. ثم لـ SSE2 ، ...pd وأضاف الإصدار أ 66 بادئة الحجم المعامل إلى ...ps وأضاف الرمز opcode ، وإصدار عدد صحيح 66 بادئة إلى إصدار MMX.

أنهم استطاع تركت orpd و/أو por, ، لكنهم لم يفعلوا. ربما ظنوا أن تصميمات وحدة المعالجة المركزية في المستقبل قد يكون لها مسارات إعادة توجيه أطول بين المجالات المختلفة ، وبالتالي فإن استخدام تعليمات المطابقة لبياناتك سيكون صفقة أكبر. على الرغم من وجود رموز opcsples منفصلة ، تعاملها AMD و Intel في وقت مبكر كلها ، مثل INT-Vector.

وفقًا لإرشادات تحسين Intel و AMD ، فإن خلط أنواع OP مع أنواع البيانات تنتج أداءً في الأداء حيث أن وحدة المعالجة المركزية داخليًا من نصفي 64 بت من السجل لنوع بيانات معين. يبدو أن هذا يؤثر في الغالب على إبطال الأنابيب حيث يتم فك تشفير التعليمات ويتم جدولة UOPS. وظيفيا أنها تنتج نفس النتيجة. تحتوي الإصدارات الأحدث لأنواع بيانات Integer على ترميز أكبر وتشغل مساحة أكبر في قطاع التعليمات البرمجية. لذلك إذا كان حجم الكود يمثل مشكلة ، فاستخدم Old Ops لأنها تحتوي على ترميز أصغر.

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