لماذا لا أرى تسريعًا كبيرًا عند استخدام مترجم MATLAB؟

StackOverflow https://stackoverflow.com/questions/137011

سؤال

لدي الكثير من أكواد MATLAB الرائعة التي تعمل ببطء شديد وسيكون من الصعب كتابتها بلغة C.لا يبدو أن مترجم MATLAB للغة C يساعد كثيرًا، هذا إن كان يساعد على الإطلاق.هل ينبغي تسريع التنفيذ أكثر؟هل أنا ثمل؟

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

المحلول

سأكرر ما قاله dwj:إذا كان كود MATLAB الخاص بك بطيئًا، فمن المحتمل أن يكون ذلك لأنه لم يتم توجيهه بشكل كافٍ.إذا كنت تقوم بتنفيذ حلقات صريحة بينما يمكنك إجراء عمليات على صفائف كاملة، فهذا هو السبب.

ينطبق هذا بالتساوي على جميع اللغات الديناميكية الموجهة نحو المصفوفة:لغة بيانات بيرل، لغة بايثون الرقمية، MATLAB/Octave، إلخ.هذا صحيح إلى حد ما في التعليمات البرمجية المجمعة لـ C و FORTRAN:تستخدم مكتبات التوجيه المصممة خصيصًا بشكل عام حلقات داخلية مشفرة يدويًا وتعليمات SIMD (على سبيل المثال.MMX، SSE، AltiVec).

نصائح أخرى

إذا كنت تستخدم ماتلاب المتوافق (في إصدار حديث من MATLAB) فمن المؤكد أنك لن ترى أي عمليات تسريع على الإطلاق.وذلك لأن كل ما يفعله المترجم في الواقع هو إعطائك طريقة لتعبئة التعليمات البرمجية الخاصة بك بحيث يمكن توزيعها على الأشخاص الذين ليس لديهم MATLAB.فهو لا يحوله إلى أي شيء أسرع (مثل رمز الآلة أو لغة C) - بل يقوم فقط بتغليفه في لغة C حتى تتمكن من الاتصال به.

يقوم بذلك عن طريق تشغيل التعليمات البرمجية الخاصة بك على MATLAB Compiler Runtime (MCR) والذي يعد في الأساس نواة MATLAB الحسابية - لا يزال يتم تفسير التعليمات البرمجية الخاصة بك.بفضل العقوبة المتكبدة بسبب الاضطرار إلى استدعاء MCR، قد تجد أن التعليمات البرمجية المجمعة تعمل بشكل أبطأ مما لو قمت بتشغيلها ببساطة على MATLAB.

وبعبارة أخرى - قد تقول أن المترجم لا يقوم بالفعل بالتجميع - بالمعنى التقليدي للكلمة على الأقل.

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

http://www.mathworks.com/support/solutions/data/1-1ARNS.html

في تجربتي، عادةً ما يأتي كود MATLAB البطيء من عدم توجيه التعليمات البرمجية الخاصة بك (أي كتابة حلقات for بدلاً من مجرد ضرب المصفوفات (مثال بسيط)).

إذا كنت تقوم بإدخال/إخراج الملفات، فاحرص على قراءة البيانات قطعة واحدة في كل مرة.ابحث في ملفات المساعدة عن الإصدار المتجه من fscanf.

لا تنس أن MATLAB يتضمن ملف تعريف أيضًا!

أولاً، أؤكد على جميع التعليقات المذكورة أعلاه حول التنميط والتوجيه.

من وجهة نظر تاريخية...

سمح الإصدار الأقدم من Matlab للمستخدم بتحويل ملفات m إلى وظائف mex عن طريق التحليل المسبق لرمز m وتحويله إلى مجموعة من استدعاءات مكتبة matlab.تحتوي هذه الاستدعاءات على جميع الأخطاء التي تم التحقق منها من قبل المترجم الفوري، ولكن الإصدارات القديمة من المترجم الفوري و/أو المحلل اللغوي عبر الإنترنت كانت بطيئة، لذا فإن تجميع الملف m قد يساعد أحيانًا.عادةً ما يكون ذلك مفيدًا عندما يكون لديك حلقات لأن Matlab كان ذكيًا بما يكفي لتضمين بعض ذلك في لغة C.إذا كان لديك أحد هذه الإصدارات من Matlab، فيمكنك محاولة إخبار البرنامج النصي mex بحفظ ملف .c ويمكنك رؤية ما يفعله بالضبط.

في الإصدار الأحدث (ربما 2006a والإصدارات الأحدث، لكنني لا أتذكر)، بدأت Mathworks في استخدام مترجم في الوقت المناسب للمترجم.في الواقع، يقوم برنامج التحويل البرمجي JIT هذا تلقائيًا بتجميع جميع وظائف mex، لذا فإن القيام بذلك بشكل صريح دون الاتصال بالإنترنت لا يساعد على الإطلاق.وفي كل إصدار منذ ذلك الحين، بذلوا أيضًا الكثير من الجهد لجعل المترجم أسرع بكثير.أعتقد أن الإصدارات الأحدث من Matlab لا تسمح لك بتجميع ملفات m تلقائيًا إلى ملفات mex لأنها لم تعد منطقية بعد الآن.

يقوم مترجم MATLAB بتجميع كود m الخاص بك وإرساله إلى وقت تشغيل MATLAB.لذلك، يجب أن يكون الأداء الذي تراه في MATLAB هو الأداء الذي تراه مع المترجم.

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

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

هل حاولت إنشاء ملف تعريف للكود الخاص بك؟لا تحتاج إلى توجيه جميع التعليمات البرمجية الخاصة بك، فقط الوظائف التي تهيمن على وقت التشغيل.سيعطيك ملف تعريف MATLAB بعض التلميحات حول المكان الذي يقضي فيه الكود الخاص بك معظم الوقت.

هناك العديد من الأشياء الأخرى التي يجب عليك قراءتها على نصائح لتحسين الأداء القسم في دليل MathWorks.

لن يقوم مركز عملائي بتسريع التعليمات البرمجية الخاصة بك على الإطلاق - فهو ليس مترجمًا حقًا.

قبل أن تستسلم، تحتاج إلى تشغيل ملف التعريف ومعرفة أين يمضي كل وقتك (الأدوات->فتح ملف التعريف).كما يمكن أن يساعد الاستخدام الحكيم لـ "tic" و"toc".لا تقم بتحسين التعليمات البرمجية الخاصة بك حتى تعرف أين يتجه الوقت (لا تحاول التخمين).

ضع في اعتبارك أنه في MATLAB:

  • العمليات على مستوى البت بطيئة حقًا
  • إدخال/إخراج الملف بطيء
  • الحلقات بطيئة بشكل عام، ولكن التحويل سريع (إذا كنت لا تعرف بناء جملة المتجهات، فتعلمها)
  • العمليات الأساسية سريعة حقًا (على سبيل المثال.ضرب المصفوفة، FFT)
  • إذا كنت تعتقد أنه يمكنك القيام بشيء أسرع في C/Fortran/etc، فيمكنك كتابة ملف MEX
  • هناك حلول تجارية لتحويل matlab إلى C (google "matlab to c") وهي تعمل

يمكنك نقل التعليمات البرمجية الخاصة بك إلى "Embedded Matlab" ثم استخدام Realtime-Workshop لترجمتها إلى C.

الماتلاب المضمن هو مجموعة فرعية من الماتلاب.وهو لا يدعم مصفوفات الخلايا، أو الرسومات، أو Marices ذات الحجم الديناميكي، أو بعض أوضاع معالجة المصفوفة.قد يستغرق الأمر جهدًا كبيرًا للوصول إلى Embedded Matlab.

تعد Realtime-Workshop جوهر منتجات إنشاء الأكواد البرمجية.إنه ينشر لغة C العامة، أو يمكنه تحسين مجموعة من الأنظمة الأساسية المضمنة.ربما يكون الأكثر إثارة للاهتمام بالنسبة لك هو xPC-Target، الذي يتعامل مع أجهزة الأغراض العامة كهدف مضمن.

سأصوت لصالح التنميط + ثم أنظر إلى ما هي الاختناقات.

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

s = [];
for i = 1:50000
  s(i) = 3;
end

يجب أن يستمر هذا في تغيير حجم المصفوفة؛من الأسرع بكثير تحديد حجم المصفوفة (ابدأ بالأصفار أو NaN) واملأها من هناك:

s = zeros(50000,1);
for i = 1:50000
  s(i) = 3;
end

إذا كان عنق الزجاجة هو عمليات التنفيذ المتكررة للعديد من استدعاءات الوظائف، فهذا أمر صعب.

إذا كان عنق الزجاجة هو الأشياء التي لا يقوم بها MATLAB بسرعة (أنواع معينة من التحليل، XML، أشياء من هذا القبيل) فسأستخدم Java نظرًا لأن MATLAB يعمل بالفعل على JVM ويتعامل بسهولة مع ملفات JAR التعسفية.لقد نظرت إلى التفاعل مع C/C++ وهو قبيح حقًا.Microsoft COM على ما يرام (على نظام التشغيل Windows فقط) ولكن بعد تعلم Java، لا أعتقد أنني سأعود إلى ذلك أبدًا.

كما لاحظ آخرون، فإن كود Matlab البطيء غالبًا ما يكون نتيجة لعدم كفاية التوجيه.

ومع ذلك، في بعض الأحيان تكون التعليمات البرمجية الموجهة بشكل مثالي بطيئة.ثم، لديك عدة خيارات أخرى:

  1. تحقق مما إذا كانت هناك أي مكتبات/صناديق أدوات يمكنك استخدامها.تمت كتابة هذه عادةً لتكون مُحسّنة للغاية.
  2. قم بتعريف الكود الخاص بك، وابحث عن النقاط الصعبة وأعد كتابتها في لغة C البسيطة.يعد توصيل كود C (مثل ملفات DLL على سبيل المثال) بـ Matlab أمرًا سهلاً ويتم تغطيته في الوثائق.

من خلال مترجم Matlab ربما تقصد الأمر mcc، الذي يعمل على تسريع الكود قليلاً عن طريق التحايل على مترجم Matlab.ما من شأنه تسريع كود MAtlab بشكل كبير (بعامل 50-200) هو استخدام كود C الفعلي الذي تم تجميعه بواسطة الأمر mex.

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