هل يجب علي إنشاء نواة Opencl متعددة لتجنب البيانات الشرطية؟
-
29-09-2019 - |
سؤال
في OpenCl ، لدي نواة تحتاج إلى العمل على بيانات معقدة وحقيقية. يمكنني وضع بيان مشروط في هذا الاتصال على السطر الصحيح من التعليمات البرمجية للتعامل مع هذا ، أو يمكن أن يكون لديّ حلبتان أتصل به ودفع البيان المشروط إلى رمز الاتصال الخاص بي.
من الواضح أن هذا سيء بالنسبة للصيانة ، ولكن هل هو مهم بالنسبة للأداء؟
المحلول
إذا كان هذا مجرد بيان مشروط ، فإن اختلاف الأداء في تجربتي لا يكاد يذكر تمامًا ، على الأقل على أجهزة NVIDIA.
في الأساس ، طالما أن جميع عناصر العمل (أو معظمها) تتبع مسار الكود نفسه ، فأنت بخير. نظرًا لأن مسار الكود يعتمد على حجة kernel في قضيتك ، فإن جميع عناصر العمل تتبع نفس المسار.
نصائح أخرى
يعتمد قليلاً على مكان الشرطية. رمز لقدرة القراءة أولاً ، ثم الأداء بعد قياسه ووجدت أنه مشكلة
على سبيل المثال. يبدو أن kernel_for_rgb_image و kernel_for_abgr_image يبدو وكأنه استخدام معقول ، قد تكون نواة مختلفة لإلغاء بعض الحلقة الداخلية العميقة بمثابة صداع أكبر للصيانة.
أعتقد أن أفضل طريقة هي المحاولة في الواقع وقياس نوعين. في بعض الحالات ، يمكن أن يؤدي وجود كتل مشروطة متعددة ، حتى لو تم تنفيذ واحد منها فقط ، يمكن أن يؤدي إلى أداء أسوأ. والسبب هو GPRS (سجلات الأغراض العامة): يخصص المترجم العديد من السجلات ، كما هو مطلوب لأسوأ الحالات.
يمكنني أن أقترح مثل هذا الحل: هل لديك وظيفة kernel واحدة ، ولكن مع نظام الترجمة الشرطي:
__kernel void work()
{
#if VAR
// one code
#else
// another code
#endif
}
ثم تحتاج إلى إعادة ترجمة النواة مع true
/false
ضبط ل VAR
عند تغيير الحالة. من الواضح ، بالنسبة للمترجم ، لا يختلف عن اثنين من النواة ، ولكن قد يكون الحفاظ عليه أفضل ، إذا كان جزء من الكود هو نفسه بالنسبة لتلك النواة.