في البداية ، كتبت هذا المستند قبل عدة سنوات ، كمهندس تحقق أساسي للتنفيذ في ARM. بالطبع ، تأثر رأيي بالعمل المتعمق مع النوى التنفيذية لمختلف المعالجات. لذا قم بذلك للحصول على خصم ، من فضلك: ربما أنا قاطع للغاية.
ومع ذلك ، ما زلت أعتقد أن المبدعين من RISC-V يمكن أن يفعلوا أفضل بكثير. من ناحية أخرى ، إذا كنت قد صممت معالجًا 32 بت أو 64 بت اليوم ، فمن المحتمل أن أطبق مثل هذه البنية للاستفادة من الأدوات الحالية.
وصف المقال أصلاً مجموعة التعليمات RISC-V 2.0. بالنسبة للإصدار 2.2 ، قامت ببعض التحديثات.
المقدمة الأصلية: بعض الرأي الشخصي
تم تخفيض مجموعة تعليمات RISC-V إلى الحد الأدنى المطلق. يتم إيلاء الكثير من الاهتمام لتقليل عدد التعليمات ، وتطبيع الترميز ، وما إلى ذلك. وقد أدت هذه الرغبة في بساطتها إلى تعامد كاذب (مثل إعادة استخدام نفس التعليمات للانتقالات والمكالمات والعوائد) واللفظ الإلزامي الذي يؤدي إلى تضخيم الحجم والكمية تعليمات.
على سبيل المثال ، إليك رمز C:
int readidx(int *p, size_t idx) { return p[idx]; }
هذه حالة بسيطة لفهرسة صفيف ، وهي عملية شائعة جدًا. هذا هو التجميع لـ x86_64:
mov eax, [rdi+rsi*4] ret
أو أرمينيا:
ldr r0, [r0, r1, lsl #2] bx lr // return
ومع ذلك ، بالنسبة إلى RISC-V ، فإن الكود التالي مطلوب:
slli a1, a1, 2 add a0, a1, a1 lw a0, a0, 0 jalr r0, r1, 0 // return
يبسط RISC-V وحدة فك الترميز (أي الواجهة الأمامية لوحدة المعالجة المركزية) عن طريق تنفيذ مزيد من الإرشادات. ولكن توسيع نطاق خط الأنابيب يمثل مشكلة صعبة ، في حين أن فك تشفير التعليمات غير المنتظمة قليلاً (أو بقوة) يتم تنفيذه جيدًا (تنشأ الصعوبة الرئيسية عندما يكون من الصعب تحديد طول التعليمات: هذا واضح بشكل خاص في مجموعة تعليمات x86 التي تحتوي على العديد من البادئات).
يجب ألا يتم تبسيط مجموعة التعليمات إلى الحد الأقصى. يعد تسجيل وتسجيل الإضافة مع تحول في ذاكرة التسجيل تعليمة بسيطة وشائعة جدًا في البرامج ، ومن السهل جدًا على المعالج تنفيذها بشكل فعال. إذا كان المعالج غير قادر على تنفيذ التعليمات مباشرة ، فيمكن أن يكون من السهل نسبيًا تقسيمها إلى مكوناتها ؛ هذه مشكلة أبسط بكثير من دمج تسلسل العمليات البسيطة.
يجب أن نميز بين الإرشادات "المعقدة" المحددة لمعالجات CISC - التعليمات المعقدة والنادرة الاستخدام وغير الفعالة - من الإرشادات "الوظيفية" الشائعة إلى معالجات CISC و RISC ، والتي تجمع بين سلسلة صغيرة من العمليات. تستخدم الأخيرة بشكل متكرر وبأداء عالٍ.
التنفيذ المتوسط
- التمدد غير محدود تقريبا. على الرغم من أن هذا هو هدف RISC-V ، إلا أنه يخلق نظامًا بيئيًا مجزأًا وغير متوافق ويجب إدارته بحذر شديد.
- يتم استخدام نفس التعليمات (
JALR
) JALR
غير المباشرة للتسجيل ، حيث يلزم فك تشفير إضافي للتنبؤ بالفرع
- اتصل:
Rd
= R1
- العودة:
Rd
= R0
، Rs
= R1
- انتقال غير مباشر:
Rd
= R0
، Rs
≠ R1
- (انتقال غريب:
Rd
≠ R0
، Rd
≠ R1
)
- لا يتم المزامنة الذاتية للترميز ذي الطول المتغير لحقل التسجيل (وهذا أمر شائع - على سبيل المثال ، مشكلة مماثلة في x86 و Thumb-2 - لكن هذا يسبب مشاكل متنوعة في كل من التطبيق والأمان ، على سبيل المثال ، البرمجة ذات الاتجاه العكسي ، مثل هجمات ROP )
- يتطلب RV64I امتداد حروف لجميع قيم 32 بت. هذا يؤدي إلى حقيقة أن النصف العلوي من سجلات 64 بت يصبح من المستحيل استخدامه لتخزين النتائج الوسيطة ، مما يؤدي إلى وضع خاص غير ضروري للنصف العلوي من السجلات. من الأفضل استخدام الامتداد باستخدام الأصفار (لأنه يقلل من عدد المحولات ويمكن عادةً تحسينه من خلال تتبع بت "صفر" عندما يكون النصف العلوي معروفًا بصفر)
- الضرب اختياري. على الرغم من أن كتل الضرب السريع يمكن أن تشغل مساحة كبيرة جدًا على البلورات الصغيرة ، إلا أنه يمكنك دائمًا استخدام دوائر أبطأ قليلاً تستخدم بنشاط ALU الحالي لدورات الضرب المتعددة.
LR
/ SC
متطلبات تقدم صارمة لمجموعة فرعية محدودة من التطبيقات. على الرغم من أن هذا التقييد صارم تمامًا ، إلا أنه قد يخلق بعض المشكلات للتطبيقات الصغيرة (خاصة بدون ذاكرة التخزين المؤقت)
- هذا يبدو وكأنه بديل لتعليمات CAS ، انظر التعليق أدناه
- توجد وحدات البت اللاصقة للذاكرة FP ووضع التقريب في نفس السجل. يتطلب ذلك إجراء تسلسل لقناة FP إذا تم تنفيذ عملية RMW لتغيير وضع التقريب.
- تعليمات
FP
مشفرة بدقة 32 و 64 و 128 بت ، ولكن ليس 16 بت (وهو أكثر شيوعًا في الأجهزة من 128 بت)
- يمكن إصلاح ذلك بسهولة: رمز البعد
0b10
مجاني.
- تحديث: يظهر العنصر النائب العشري في الإصدار 2.2 ، ولكن لا يوجد عنصر نائب نصف الدقة. العقل غير مفهومة.
- لم يتم تعريف الطريقة التي يتم بها تمثيل قيم FP في ملف سجل FP ، ولكن يمكن ملاحظتها (عبر التحميل / المتجر)
- سوف الكتاب المحاكي يكرهونك
- هجرة الأجهزة الافتراضية قد تصبح مستحيلة
- تحديث: يتطلب الإصدار 2.2 قيم NN-boxing أوسع
سيئة
- لا توجد أكواد شرط ، وبدلاً من ذلك يتم استخدام بيانات المقارنة والفرع. هذه ليست مشكلة في حد ذاتها ، ولكن العواقب غير سارة:
- انخفاض مساحة الترميز في الفروع الشرطية بسبب الحاجة إلى تشفير واحد أو اثنين من محددات السجل
- لا يوجد خيار شرطي (مفيد للتحولات غير المتوقعة للغاية)
- لا يوجد ترحيل / طرح مع ترحيل أو استعارة
- (لاحظ أن هذا لا يزال أفضل من مجموعات الأوامر التي تكتب الإشارات إلى السجل العام ، ثم قم بالتبديل إلى العلامات المستلمة)
- يبدو أن العدادات عالية الدقة (دورات الأجهزة) مطلوبة في ISA غير محدود. في الممارسة العملية ، يعد تزويدهم بالتطبيقات متجهًا ممتازًا للهجمات على قنوات الجهات الخارجية
- الضرب والقسمة جزء من نفس الامتداد ، ويبدو أنه إذا تم تنفيذ أحدهما ، فيجب أن يكون الآخر كذلك. الضرب أبسط بكثير من القسمة ، وهو شائع في معظم المعالجات ، لكن القسمة ليست كذلك.
- لا توجد تعليمات ذرية في بنية مجموعة التعليمات الأساسية. أصبحت وحدات التحكم الدقيقة متعددة النواة أكثر شيوعًا ، لذا فإن الإرشادات الذرية مثل LL / SC غير مكلفة (لتحقيق الحد الأدنى من التنفيذ داخل معالج واحد متعدد النواة ، لا يلزم سوى حالة واحدة فقط من حالة المعالج)
LR
/ SC
هي في نفس امتداد التعليمات الذرية الأكثر تعقيدًا ، مما يحد من مرونة التطبيقات الصغيرة
- لا تشمل التعليمات الذرية العامة (وليس
LR
/ SC
) CAS
CmpHi:CmpLo
تجنب الحاجة إلى تعليمة تقرأ خمس سجلات ( CmpHi:CmpLo
، CmpHi:CmpLo
، SwapHi:SwapLo
) ، ولكن من المحتمل أن يفرض هذا حمولة أقل للتنفيذ مقارنةً بـ LR
/ SC
المقدمة المضمونة ، والتي يتم توفيرها على النحو التالي: بديل
- يتم تقديم الإرشادات الذرية التي تعمل على قيم 32 بت و 64 بت ، ولكن ليس على قيم 8 بت أو 16 بت
- بالنسبة إلى RV32I ، لا توجد طريقة لنقل قيمة DP FP بين عدد صحيح وملف سجل FP ، إلا من خلال الذاكرة ، فمن سجلات عدد صحيح 32 بت أنه من المستحيل عمل رقم فاصلة مزدوج الدقة 64 بت ، يجب أولاً كتابة القيمة الوسيطة على الذاكرة وتحميلها له في ملف السجل من هناك
- على سبيل المثال ، تحتوي التعليمات
ADD
32 بت في RV32I و ADD 64 بت في RVI64 على نفس الترميزات ، وفي RVI64 ADD.W
تشفير ADD.W
آخر. هذا تعقيد غير ضروري بالنسبة للمعالج الذي ينفذ كلا الإرشادات - سيكون من الأفضل إضافة تشفير 64 بت جديد بدلاً من ذلك.
- لا تعليمات
MOV
. تتم ترجمة رمز ذاكري للأمر MV
بواسطة المجمّع إلى التعليمة MV rD, rS
-> ADDI rD, rS, 0
. عادةً ما تقوم المعالجات عالية الأداء بتحسين إرشادات MOV
، مع إعادة ترتيب التعليمات على نطاق واسع. تم اختيار تعليمة ذات معامل مباشر 12 بت كشكل أساسي لتعليم MV
في RISC-V.
- في حالة عدم وجود
MOV
تصبح التعليمة ADD rD, rS, r0
مفضلة فعليًا على MOV
الكنسي ، حيث أنه من الأسهل فك ADD rD, rS, r0
وعادة ما يتم تحسين العمليات التي لها سجل صفري (r0) في وحدة المعالجة المركزية
رهيب
- تنفق
JAL
5 بت على ترميز سجل الاتصالات ، والذي يساوي دائمًا R1
(أو R0
)
- هذا يعني أن RV32I يستخدم إزاحة فرع 21 بت. هذا لا يكفي للتطبيقات الكبيرة - على سبيل المثال ، متصفحات الويب - دون استخدام تسلسلات متعددة من الأوامر و / أو "الجزر الفرعية"
- هذا تدهور مقارنة بالإصدار 1.0 من بنية القيادة!
- على الرغم من الجهد الكبير الذي يتم ترميزه بشكل موحد ، يتم ترميز تعليمات التحميل / التخزين بشكل مختلف (تتغير حالة الأحرف والحقول المباشرة)
- على ما يبدو ، كان التعامد الترميز لسجل المخرجات مفضلًا على متعامد الترميز لتعليمين مرتبطين بقوة. يبدو هذا الاختيار غريبًا بعض الشيء نظرًا لأن توليد العناوين يعد وقتًا أكثر أهمية.
- لا توجد إرشادات تحميل الذاكرة مع إزاحة التسجيل (
Rbase
+ Roffset
) أو الفهارس ( Rbase
+ Rindex
<< Scale
).
- يعني
FENCE.I
مزامنة كاملة لذاكرة التخزين المؤقت للتعليمات مع جميع المستودعات السابقة ، مع أو بدون سياج. تحتاج التطبيقات إما إلى مسح جميع I $ على السياج ، أو البحث عن D $ ومخزن التخزين المؤقت
- في RV32I ، تتطلب قراءة عدادات 64 بت قراءة النصف العلوي مرتين ، والمقارنة والتفرع في حالة النقل بين النصف السفلي والعلوي أثناء عملية القراءة
- نموذجياً ، تتضمن ISAs 32 بت إرشادات سجل قراءة زوج خاص لتجنب هذه المشكلة.
- لا توجد مساحة محددة معمارياً لترميز التلميح ، بحيث لا تتسبب الإرشادات الواردة من هذه المساحة في حدوث خطأ في المعالجات القديمة (تتم معالجتها كـ
NOP
) ، ولكنها تفعل شيئًا على وحدات المعالجة المركزية الحديثة
- أمثلة نموذجية من تلميحات NOP نقية هي أشياء مثل العائد spinlock
- تحتوي المعالجات الأحدث أيضًا على تلميحات أكثر تطوراً (مع تأثيرات جانبية مرئية على المعالجات الأحدث ؛ على سبيل المثال ، يتم ترميز تعليمات فحص الحدود إلى x86 في مساحة التلميح بحيث تظل الثنائيات متوافقة مع الإصدارات السابقة)