كيفية التعامل مع وحدات معالجة الرسومات المتفرعة

صورة

حول المادة


هذا المنشور هو ملاحظة قصيرة للمبرمجين الذين يرغبون في معرفة المزيد حول كيفية معالجة GPU للفروع. يمكنك اعتباره مقدمة لهذا الموضوع. أوصي ببدء النظر في [ 1 ] و [ 2 ] و [ 8 ] للحصول على فكرة عن كيف يبدو نموذج تنفيذ GPU بشكل عام ، لأننا سننظر في تفاصيل منفصلة واحدة فقط. للقراء الفضوليين ، هناك كل الروابط في نهاية المنشور. إذا وجدت أخطاء ، اتصل بي.

محتوى


  • حول المادة
  • محتوى
  • قاموس
  • كيف هو جوهر GPU مختلفة عن وحدة المعالجة المركزية الأساسية؟
  • ما هو الاتساق / التناقض؟
  • أمثلة على معالجة قناع التنفيذ
    • ISA الخيالية
    • AMD GCN ISA
    • AVX512
  • كيفية التعامل مع التناقض؟
  • مراجع

قاموس


  • GPU - وحدة معالجة الرسومات ، GPU
  • تصنيف فلين
    • SIMD - تعليمات واحدة بيانات متعددة ، دفق تعليمات واحدة ، دفق بيانات متعددة
    • SIMT - تعليمات متعددة المواضيع واحد ، تيار تعليمات واحدة ، مواضيع متعددة
  • Wave (SIM) - دفق يتم تنفيذه في وضع SIMD
  • الخط (الخط) - دفق بيانات منفصل في نموذج SIMD
  • SMT - تزامن متعدد الخيوط ، تعدد مؤشرات ترابطية متزامنة (إنتل Hyper-threading) [ 2 ]
    • مؤشرات الترابط متعددة مشاركة الموارد الحوسبة الأساسية
  • IMT - ترابط متعدد الخيوط ، وتعدد مؤشرات ترابط [ 2 ]
    • تشارك مؤشرات الترابط المتعددة إجمالي موارد الحوسبة في kernel ، ولكن واحدة فقط
  • BB - كتلة أساسية ، كتلة أساسية - سلسلة خطية من التعليمات مع قفزة واحدة في النهاية
  • ILP - مستوى التدريس التوازي ، التوازي في مستوى التعليم [ 3 ]
  • ISA - مجموعة هندسة التدريس ، هندسة مجموعة التعليمات

في مشاركتي ، سألتزم بهذا التصنيف المبتكر. يشبه تقريبا كيفية تنظيم GPU الحديثة.

:
GPU -+
|- 0 -+
| |- 0 +
| | |- 0
| | |- 1
| | |- ...
| | +- Q-1
| |
| |- ...
| +- M-1
|
|- ...
+- N-1

* - SIMD

:
+
|- 0
|- ...
+- N-1

أسماء أخرى:

  • قد يسمى جوهر CU ، SM ، الاتحاد الأوروبي
  • يمكن أن تسمى موجة واجهة الموجة ، مؤشر ترابط الأجهزة (مؤشر ترابط HW) ، الاعوجاج ، سياق
  • يمكن استدعاء سطر مؤشر ترابط البرنامج (مؤشر ترابط SW)

كيف هو جوهر GPU مختلفة عن وحدة المعالجة المركزية الأساسية؟


أي جيل حالي من نوى GPU أقل قوة من المعالجات المركزية: ILP / multi-issue [ 6 ] والإعداد المسبق [ 5 ] ، لا تنبؤات أو تنبؤات بالانتقالات / العوائد. كل هذا ، إلى جانب مخابئ صغيرة ، يحرر مساحة كبيرة إلى حد ما على الرقاقة ، المليئة بالعديد من النوى. آليات تحميل / تخزين الذاكرة قادرة على التعامل مع عرض القناة بترتيب أكبر من الحجم (لا ينطبق هذا على وحدات معالجة الرسومات المدمجة / المتنقلة) من وحدات المعالجة المركزية التقليدية ، ولكن عليك أن تدفع مقابل ذلك مع الكمون العالية. لإخفاء زمن الوصول ، يستخدم GPU SMT [ 2 ] - في حين أن موجة واحدة خامدة ، يستخدم آخرون موارد الحوسبة المجانية للنواة. عادةً ما يعتمد عدد الموجات التي تتم معالجتها بواسطة قلب واحد على السجلات المستخدمة ويتم تحديده ديناميكيًا عن طريق تخصيص ملف سجل ثابت [ 8 ]. التخطيط لتنفيذ التعليمات هجين - ديناميكي ثابت [ 6 ] [ 11 4.4]. تحقق نواة SMT المنفذة في وضع SIMD قيم FLOPS عالية (عمليات النقطة العائمة في الثانية ، يتخبط ، عدد عمليات الفاصلة العائمة في الثانية).

الشكل 1

مخطط أسطورة. أسود - غير نشط ، أبيض - نشط ، رمادي - إيقاف ، أزرق - خمول ، أحمر - معلق


الشكل 1. 4: 2 تاريخ التنفيذ

تُظهر الصورة محفوظات قناع التنفيذ ، حيث يُظهر المحور السيني الوقت الذي يمتد من اليسار إلى اليمين ، بينما يُظهر المحور ص مُعرّف الخط الذي ينتقل من الأعلى إلى الأسفل. إذا كنت لا تزال لا تفهم هذا ، فعد إلى الرسم بعد قراءة الأقسام التالية.

هذا مثال على كيفية ظهور سجل تنفيذ GPU الأساسي في شكل وهمي: تشترك أربع موجات في عينة واحدة واثنين من وحدات ALU. يقوم مخطط الموجة في كل دورة بإصدار تعليميين من موجتين. عندما تكون الموجة في وضع الخمول عند إجراء الوصول إلى الذاكرة أو تشغيل ALU طويل ، ينتقل المجدول إلى زوج آخر من الأمواج ، بسبب أن ALU مشغولة باستمرار بنسبة 100٪ تقريبًا.


الشكل 2. 4: 1 تاريخ التنفيذ

مثال مع الحمل نفسه ، ولكن هذه المرة في كل دورة من التعليمات مشاكل موجة واحدة فقط. لاحظ أن ALU الثاني يتضورون جوعًا.


الشكل 3. تاريخ التنفيذ 4: 4

هذه المرة ، يتم إصدار أربعة تعليمات في كل دورة. لاحظ أن هناك الكثير من الطلبات إلى ALU ، لذلك تنتظر موجتان دائمًا تقريبًا (في الواقع ، هذا خطأ في خوارزمية التخطيط).

تحديث لمزيد من المعلومات حول صعوبات التخطيط لتنفيذ التعليمات ، انظر [ 12 ].

في العالم الواقعي ، تحتوي وحدات معالجة الرسومات (GPU) على تكوينات أساسية مختلفة: يمكن أن يحتوي بعضها على ما يصل إلى 40 موجة لكل قلب و 4 وحدات (وحدات) ، والبعض الآخر لديه 7 موجات ثابتة و 2 وحدة (وحدات). كل هذا يعتمد على العديد من العوامل ويتم تحديده بفضل عملية مضنية لمحاكاة الهندسة المعمارية.

بالإضافة إلى ذلك ، قد يكون للوحدات SIMD الحقيقية عرض أضيق من الموجات التي تخدمها ، ومن ثم يستغرق الأمر عدة دورات لمعالجة تعليمات واحدة صادرة ؛ يسمى العامل طول "الرنين" [ 3 ].

ما هو الاتساق / التناقض؟


دعنا نلقي نظرة على مقتطف الشفرة التالي:

مثال 1

 uint lane_id = get_lane_id(); if (lane_id & 1) { // Do smth } // Do some more 

نرى هنا مجموعة من التعليمات التي يعتمد مسار التنفيذ فيها على معرف الخط الذي يتم تنفيذه. من الواضح أن الخطوط المختلفة لها معان مختلفة. ماذا سيحدث؟ هناك طرق مختلفة لحل هذه المشكلة [ 4 ] ، ولكن في النهاية يفعلون جميعًا نفس الشيء. أحد هذه الأساليب هو قناع التنفيذ ، الذي سأغطيه. وقد استخدم هذا النهج في نفيديا GPUs قبل فولتا وفي وحدات معالجة الرسومات AMD GCN. النقطة الرئيسية في قناع التنفيذ هي أننا نخزن قليلاً لكل سطر في الموجة. إذا كانت بتة تنفيذ السطر المقابل هي 0 ، فلن تتأثر أي سجلات بالتعليمات التالية الصادرة. في الواقع ، يجب ألا يشعر الخط بتأثير التعليمة المنفذة بالكامل ، لأن بت التنفيذ الخاص به هو 0. يعمل هذا على النحو التالي: تنتقل الموجة عبر الرسم البياني لتدفق التحكم في ترتيب البحث العميق ، مما يوفر محفوظات الانتقالات المحددة حتى يتم ضبط البتات. أعتقد أنه من الأفضل إظهار ذلك بمثال.

افترض أن لدينا موجات بعرض 8. فيما يلي شكل قناع التنفيذ الخاص بجزء التعليمات البرمجية:

مثال 1. تاريخ قناع التنفيذ

  // execution mask uint lane_id = get_lane_id(); // 11111111 if (lane_id & 1) { // 11111111 // Do smth // 01010101 } // Do some more // 11111111 

الآن النظر في أمثلة أكثر تعقيدا:

مثال 2

 uint lane_id = get_lane_id(); for (uint i = lane_id; i < 16; i++) { // Do smth } 

مثال 3

 uint lane_id = get_lane_id(); if (lane_id < 16) { // Do smth } else { // Do smth else } 

قد تلاحظ أن التاريخ ضروري. عند استخدام نهج قناع التنفيذ ، عادة ما تستخدم المعدات نوعًا من المكدس. تتمثل الطريقة الساذجة في تخزين مجموعة من المجموعات (exec_mask ، العنوان) وإضافة إرشادات التقارب التي تسترجع القناع من المكدس وتغيير مؤشر التعليمات للموجة. في هذه الحالة ، سيكون للموجة معلومات كافية لتجاوز CFG بالكامل لكل سطر.

فيما يتعلق بالأداء ، لا يستغرق الأمر سوى بضع حلقات لمعالجة تعليمة تدفق التحكم بسبب كل تخزين البيانات هذا. ولا تنس أن المكدس له عمق محدود.

التحديث. بفضل craigkolb ، قرأت مقالة [ 13 ] ، تشير إلى أن تعليمات شوكة / صلة AMD GCN تحدد أولاً مسارًا من عدد أقل من سلاسل العمليات [ 11 4.6] ، مما يضمن أن عمق كومة القناع يساوي log2.

التحديث. من الواضح ، أنه من الممكن دائمًا تقريبًا تضمين كل شيء في تظليل / بنية CFG في تظليل ، وبالتالي تخزين السجل الكامل لأقنعة التنفيذ في السجلات والتخطيط لتجاوز / دمج CFG بشكل ثابت [ 15 ]. بعد النظر إلى الواجهة الخلفية لـ LLVM لـ AMDGPU ، لم أجد أي دليل على معالجة المكدس الصادرة باستمرار عن المترجم.

دعم الأجهزة وقت التشغيل قناع


الآن نلقي نظرة على هذه الرسوم البيانية تدفق التحكم من ويكيبيديا:


الشكل 4. بعض أنواع الرسوم البيانية التحكم في التدفق

ما هو الحد الأدنى لمجموعة إرشادات التحكم في القناع التي نحتاجها للتعامل مع جميع الحالات؟ إليك ما يبدو عليه في ISA المعياري الاصطناعي الخاص بي مع التوازي الضمني والتحكم الواضح في القناع والتزامن الديناميكي الكامل لتعارضات البيانات:

 push_mask BRANCH_END ; Push current mask and reconvergence pointer pop_mask ; Pop mask and jump to reconvergence instruction mask_nz r0.x ; Set execution bit, pop mask if all bits are zero ; Branch instruction is more complicated ; Push current mask for reconvergence ; Push mask for (r0.x == 0) for else block, if any lane takes the path ; Set mask with (r0.x != 0), fallback to else in case no bit is 1 br_push r0.x, ELSE, CONVERGE 

دعنا نلقي نظرة على القضية د).

 A: br_push r0.x, C, D B: C: mask_nz r0.y jmp B D: ret 

أنا لست متخصصًا في تحليل تدفقات التحكم أو تصميم ISA ، لذلك أنا متأكد من أن هناك حالة لا يمكن لـ ISA المعياري التعامل معها ، لكن هذا ليس مهمًا ، لأن CFG المهيكل يجب أن يكون كافياً للجميع.

التحديث. اقرأ المزيد عن دعم GCN لتعليمات تدفق التحكم هنا: [ 11 ] الفصل 4 ، وتنفيذ LLVM هنا: [ 15 ].

الاستنتاج:

  • الاختلاف - الفرق الناتج في المسارات التي تختارها خطوط مختلفة من نفس الموجة
  • الاتساق - لا يوجد تباين.

أمثلة على معالجة قناع التنفيذ


ISA الخيالية


قمت بتجميع مقتطفات الشفرة السابقة في ISA الاصطناعي الخاص بي وتشغيلها على جهاز محاكاة في SIMD32. انظر كيف يتعامل مع قناع التنفيذ.

التحديث. لاحظ أن المحاكاة الاصطناعية تختار دائمًا المسار الحقيقي ، وهذه ليست الطريقة الأفضل.

مثال 1

 ; uint lane_id = get_lane_id(); mov r0.x, lane_id ; if (lane_id & 1) { push_mask BRANCH_END and r0.y, r0.x, u(1) mask_nz r0.y LOOP_BEGIN: ; // Do smth pop_mask ; pop mask and reconverge BRANCH_END: ; // Do some more ret 

الشكل 5

الشكل 5. تاريخ المثال 1

هل لاحظت منطقة سوداء؟ هذا الوقت يضيع. بعض الخطوط تنتظر الآخرين لإكمال التكرار.

مثال 2

 ; uint lane_id = get_lane_id(); mov r0.x, lane_id ; for (uint i = lane_id; i < 16; i++) { push_mask LOOP_END ; Push the current mask and the pointer to reconvergence instruction LOOP_PROLOG: lt.u32 r0.y, r0.x, u(16) ; r0.y <- r0.x < 16 add.u32 r0.x, r0.x, u(1) ; r0.x <- r0.x + 1 mask_nz r0.y ; exec bit <- r0.y != 0 - when all bits are zero next mask is popped LOOP_BEGIN: ; // Do smth jmp LOOP_PROLOG LOOP_END: ; // } ret 

الشكل 6

الشكل 6. تاريخ المثال 2

مثال 3

  mov r0.x, lane_id lt.u32 r0.y, r0.x, u(16) ; if (lane_id < 16) { ; Push (current mask, CONVERGE) and (else mask, ELSE) ; Also set current execution bit to r0.y != 0 br_push r0.y, ELSE, CONVERGE THEN: ; // Do smth pop_mask ; } else { ELSE: ; // Do smth else pop_mask ; } CONVERGE: ret 

الشكل 7

الشكل 7. تاريخ المثال 3

AMD GCN ISA


التحديث. تستخدم GCN أيضًا معالجة القناع الصريح ، ويمكن الاطلاع على المزيد حول هذا الأمر هنا: [ 11 4.x]. قررت أن أعرض بعض الأمثلة من ISA ، وبفضل ملعب التظليل ، من السهل القيام بذلك. ربما في يوم من الأيام سأجد محاكيًا وأتمكن من الحصول على المخططات.

ضع في اعتبارك أن المترجم ذكي ، بحيث يمكنك الحصول على نتائج أخرى. حاولت خداع المحول البرمجي حتى لا يعمل على تحسين فروعي من خلال وضع حلقات مؤشر ثم تنظيف رمز المجمّع ؛ أنا لست متخصصًا في GCN ، لذا قد يتم تخطي بضع nop مهمة.

لاحظ أيضًا أنه لا يتم استخدام إرشادات S_CBRANCH_I / G_FORK و S_CBRANCH_JOIN في هذه الأجزاء لأنها بسيطة ولا يدعمها المترجم. لذلك ، لسوء الحظ ، لم يكن من الممكن التفكير في كومة الأقنعة. إذا كنت تعرف كيفية إجراء معالجة مكدس مشكلة برنامج التحويل البرمجي ، فيرجى إخبارنا بذلك.

التحديث. تحقق من هذا @ SiNGUL4RiTY الحديث عن تنفيذ تدفق التحكم الموجه في LLVM الخلفية المستخدمة من قبل AMD.

مثال 1

 ; uint lane_id = get_lane_id(); ; GCN uses 64 wave width, so lane_id = thread_id & 63 ; There are scalar s* and vector v* registers ; Executon mask does not affect scalar or branch instructions v_mov_b32 v1, 0x00000400 ; 1024 - group size v_mad_u32_u24 v0, s12, v1, v0 ; thread_id calculation v_and_b32 v1, 63, v0 ; if (lane_id & 1) { v_and_b32 v2, 1, v0 s_mov_b64 s[0:1], exec ; Save the execution mask v_cmpx_ne_u32 exec, v2, 0 ; Set the execution bit s_cbranch_execz ELSE ; Jmp if all exec bits are zero ; // Do smth ELSE: ; } ; // Do some more s_mov_b64 exec, s[0:1] ; Restore the execution mask s_endpgm 

مثال 2

 ; uint lane_id = get_lane_id(); v_mov_b32 v1, 0x00000400 v_mad_u32_u24 v0, s8, v1, v0 ; Not sure why s8 this time and not s12 v_and_b32 v1, 63, v0 ; LOOP PROLOG s_mov_b64 s[0:1], exec ; Save the execution mask v_mov_b32 v2, v1 v_cmp_le_u32 vcc, 16, v1 s_andn2_b64 exec, exec, vcc ; Set the execution bit s_cbranch_execz LOOP_END ; Jmp if all exec bits are zero ; for (uint i = lane_id; i < 16; i++) { LOOP_BEGIN: ; // Do smth v_add_u32 v2, 1, v2 v_cmp_le_u32 vcc, 16, v2 s_andn2_b64 exec, exec, vcc ; Mask out lanes which are beyond loop limit s_cbranch_execnz LOOP_BEGIN ; Jmp if non zero exec mask LOOP_END: ; // } s_mov_b64 exec, s[0:1] ; Restore the execution mask s_endpgm 

مثال 3

 ; uint lane_id = get_lane_id(); v_mov_b32 v1, 0x00000400 v_mad_u32_u24 v0, s12, v1, v0 v_and_b32 v1, 63, v0 v_and_b32 v2, 1, v0 s_mov_b64 s[0:1], exec ; Save the execution mask ; if (lane_id < 16) { v_cmpx_lt_u32 exec, v1, 16 ; Set the execution bit s_cbranch_execz ELSE ; Jmp if all exec bits are zero ; // Do smth ; } else { ELSE: s_andn2_b64 exec, s[0:1], exec ; Inverse the mask and & with previous s_cbranch_execz CONVERGE ; Jmp if all exec bits are zero ; // Do smth else ; } CONVERGE: s_mov_b64 exec, s[0:1] ; Restore the execution mask ; // Do some more s_endpgm 

AVX512


التحديث. أوضحت ليtom_forsyth أن امتداد AVX512 يحتوي أيضًا على معالجة قناع واضحة ، لذا إليك بعض الأمثلة. يمكن العثور على مزيد من التفاصيل حول هذا في [ 14 ] ، 15.x و 15.6.1. ليس بالضبط GPU ، ولكن لا يزال لديه SIMD16 حقيقي مع 32 بت. تم إنشاء مقتطفات الشفرة باستخدام godbolt ISPC (–target = avx512knl-i32x16) وتم إعادة تصميمها بشكل كبير ، لذا فقد لا تكون صحيحة بنسبة 100٪.

مثال 1

  ; Imagine zmm0 contains 16 lane_ids ; AVXZ512 comes with k0-k7 mask registers ; Usage: ; op reg1 {k[7:0]}, reg2, reg3 ; k0 can not be used as a predicate operand, only k1-k7 ; if (lane_id & 1) { vpslld zmm0 {k1}, zmm0, 31 ; zmm0[i] = zmm0[i] << 31 kmovw eax, k1 ; Save the execution mask vptestmd k1 {k1}, zmm0, zmm0 ; k1[i] = zmm0[i] != 0 kortestw k1, k1 je ELSE ; Jmp if all exec bits are zero ; // Do smth ; Now k1 contains the execution mask ; We can use it like this: ; vmovdqa32 zmm1 {k1}, zmm0 ELSE: ; } kmovw k1, eax ; Restore the execution mask ; // Do some more ret 

مثال 2

  ; Imagine zmm0 contains 16 lane_ids kmovw eax, k1 ; Save the execution mask vpcmpltud k1 {k1}, zmm0, 16 ; k1[i] = zmm0[i] < 16 kortestw k1, k1 je LOOP_END ; Jmp if all exec bits are zero vpternlogd zmm1 {k1}, zmm1, zmm1, 255 ; zmm1[i] = -1 ; for (uint i = lane_id; i < 16; i++) { LOOP_BEGIN: ; // Do smth vpsubd zmm0 {k1}, zmm0, zmm1 ; zmm0[i] = zmm0[i] + 1 vpcmpltud k1 {k1}, zmm0, 16 ; masked k1[i] = zmm0[i] < 16 kortestw k1, k1 jne LOOP_BEGIN ; Break if all exec bits are zero LOOP_END: ; // } kmovw k1, eax ; Restore the execution mask ; // Do some more ret 

مثال 3

  ; Imagine zmm0 contains 16 lane_ids ; if (lane_id & 1) { vpslld zmm0 {k1}, zmm0, 31 ; zmm0[i] = zmm0[i] << 31 kmovw eax, k1 ; Save the execution mask vptestmd k1 {k1}, zmm0, zmm0 ; k1[i] = zmm0[i] != 0 kortestw k1, k1 je ELSE ; Jmp if all exec bits are zero THEN: ; // Do smth ; } else { ELSE: kmovw ebx, k1 andn ebx, eax, ebx kmovw k1, ebx ; mask = ~mask & old_mask kortestw k1, k1 je CONVERGE ; Jmp if all exec bits are zero ; // Do smth else ; } CONVERGE: kmovw k1, eax ; Restore the execution mask ; // Do some more ret 

كيفية التعامل مع التناقض؟


حاولت إنشاء توضيح بسيط ولكنه كامل لكيفية نشوء عدم الكفاءة من خلال الجمع بين الخطوط المتباعدة.

تخيل قطعة بسيطة من الكود:

 uint thread_id = get_thread_id(); uint iter_count = memory[thread_id]; for (uint i = 0; i < iter_count; i++) { // Do smth } 

لنقم بإنشاء 256 موضوعًا وقياس وقت تنفيذها:


الشكل 8. مدة المواضيع المتباينة

المحور س هو معرف دفق البرنامج ، المحور ص هو دورات الساعة ؛ تُظهر الأعمدة المختلفة مقدار الوقت المهدر عند تجميع التدفقات بأطوال موجية مختلفة مقارنة بالتنفيذ المفرد.

وقت تشغيل الموجة يساوي وقت التشغيل الأقصى بين الخطوط الموجودة فيه. يمكنك أن ترى أن الأداء ينخفض ​​بشكل كبير بالفعل مع SIMD8 ، والتوسع الإضافي يجعله أسوأ قليلاً.

الشكل 9

الشكل 9. وقت التشغيل من المواضيع متسقة

يتم عرض نفس الأعمدة في هذا الشكل ، ولكن في هذه المرة يتم فرز عدد التكرارات حسب معرفات الدفق ، أي ، يتم نقل التدفقات ذات عدد مماثل من التكرار إلى موجة واحدة.

في هذا المثال ، قد يتم تسريع التنفيذ بمقدار النصف تقريبًا.

بالطبع ، المثال بسيط للغاية ، لكنني آمل أن تفهم النقطة: التناقض في التنفيذ ينبع من تباين البيانات ، لذلك يجب أن تكون CFGs بسيطة وأن تكون البيانات متسقة.

على سبيل المثال ، إذا كنت تكتب جهاز تتبع للأشعة ، فقد تستفيد من تجميع الأشعة بنفس الاتجاه والموضع ، لأنها على الأرجح ستخضع لنفس العقد في BVH. انظر [ 10 ] والمقالات الأخرى ذات الصلة لمزيد من التفاصيل.

تجدر الإشارة أيضًا إلى أن هناك تقنيات للتعامل مع التناقضات على مستوى الأجهزة ، على سبيل المثال ، Dynamic Warp Formation [ 7 ] والتنفيذ المتوقع للفروع الصغيرة.

مراجع


[1] رحلة عبر خط أنابيب الرسومات

[2] كيفون فتاهاليان: الحوسبة المتوازية

[3] هندسة الكمبيوتر والنهج الكمي

[4] التقارب بين كومة SIMT بأقل تكلفة

[5] تشريح التسلسل الهرمي للذاكرة GPU من خلال وضع العلامات المصغرة

[6] تشريح بنية معالج الجرافيك NVIDIA Volta عبر ترميز Microbenchmarking

[7] التكوين الديناميكي للالتفاف والجدولة لكفاءة تدفق التحكم GPU

[8] موريزيو سيراتو: GPU Architectures

[9] لعبة محاكاة GPU

[10] تقليل تباعد الفروع في برامج GPU

[11] "Vega" مجموعة تعليمات الهندسة المعمارية

[12] جوشوا Barczak: محاكاة تنفيذ شادر ل GCN

[13] ناقلات المماس: انحدار على الاختلاف

[14] دليل مطور Intel 64 و IA-32 ArchitecturesSoftware

[15] تحويل التحكم في التدفق المتباين لتطبيقات SIMD

Source: https://habr.com/ru/post/ar457704/


All Articles