نکته ای برای افزایش سرعت اجرای برنامه ها در متلب

ترفندهای برنامه نویسی متلب - نکته ای برای افزایش سرعت اجرای برنامه ها

یکی از گله های دائمی کاربران متلب، سرعت بسیار پایین اجرای برنامه ها در متلب است. زبان متلب، یک زبان مفسری است و برنامه های نوشته شده در آن، کامپایل نمی شوند. بنابراین طبیعی است که سرعت اجرای برنامه های متلب، در مقایسه با زبان های کامپایلری، مانند C، پایین باشد. اما آیا واقعا، همه تقصیرها متوجه متلب است؟ در این مقاله آموزشی کوچک، می خواهیم نشان دهیم که چگونه می توان با رعایت اصول ساده، حداکثر سرعت قابل دسترسی در متلب را، برای برنامه ها به دست آوریم.

یکی از اشتباه هایی که بسیاری از برنامه نویسان متلب مرتکب می شوند، عدم تخصیص فضای مناسب برای آرایه ها و ماتریس ها، قبل از مقدار دهی است. زبان هایی مانند C یا #C (بخوانید سی شارپ)، در هنگام تعریف آرایه ها، اندازه آرایه ها را به صورت اجباری از برنامه نویس می خواهند و هر گاه در طول اجرای برنامه، بخواهیم که مقدار آرایه را در جایی که بیش از طول آرایه است، تغییر دهیم، برنامه خطا می دهد. اما متلب، از آن جا که سادگی را به عنوان محور اولیه در نظر گرفته است، چنین ضرورت هایی را به برنامه نویسی تحمیل نمی کند. اما مشکل دقیقا از همین جا شروع می شود. برای آرایه های کوچک، همه چیز به خوبی و خوشی تمام می شود. اما وقتی آرایه ها، از یک حد بزرگ تر می شوند، ایم مسأله واقعا دردسر ساز می شود.

در متلب، برای تخصیص فضای اولیه (Pre-Allocation)، از توابع مختلفی استفاده می شود. ازمیان این توابع، پر کاربردترین آن ها، تابع zeros است. این تابع ابعاد ماتریس مورد نظر را می گیرید، و بخشی از حافظه را به همان اندازه، برای آرایه موزذ نظر تخصیص می دهد. این کار، در زبان C، با تابع malloc انجام می شود. برای آگاهی بیشتر از چگونگی کارکرد این تابع، به راهنمای آن در هلپ متلب، مراجعه کنید.

دو برنامه زیر را در نظر بگیرید. این برنامه ها برای محاسبه تعداد زیادی از جملات سری فیبوناچی (Fibonacci)، نوشته شده است. در سری فیبوناچی، هر جمله با مجموع دو جمله قبل از خودش برابر است. جمله اول و دوم نیز، طبق قرارداد برابر با صفر و یک در نظر گرفته می شوند.

برنامه اول:

clear;
n=300000;
x(1)=0;
x(2)=1;
for k=3:n
x(k)=x(k-1)+x(k-2);
end

برنامه دوم:

clear;
n=300000;
x=zeros(1,n);     % Pre-Allocation
x(1)=0;
x(2)=1;
for k=3:n
x(k)=x(k-1)+x(k-2);
end

این دو برنامه، فقط در مورد تخصیص اولیه (خط سوم از برنامه دوم)، با هم اختلاف دارند. اما جالب است بدانید که مدت اجرای برنامه اول، بر روی کامپیوتر من، در حدود ۴ دقیقه بود. در حالی برنامه دوم، در کمتر از یک ثانیه اجرا می شود. حال فرض کنید که در یک برنامه بزرگ، این مشکلات چقدر می تواند حادتر و شدیدتر باشد.

امیدوارم این نکته آموزشی، برایتان مفید باشد. منتظر نکات بعدی باشید.

مطالب پیشنهادی‎

11 پاسخ
    • smk
      smk says:

      با سلام،
      متاسفانه در حال حاضر امکان همکاری باشما در خصوص موضوع مطرح شده، وجود ندارد.
      لطفا به این موارد توجه فرمایید:
      ۱- حتما توجه فرمایید که نظر ارائه شده در خصوص هر مطلب، کاملا مرتبط با موضوع مطلب باشد.
      ۲- از حروف الفبای فارسی و زبان فارسی برای نگارش متن نظرات خود استفاده ببرید.

      پاسخ دادن
  1. نرگس یوسفی
    نرگس یوسفی says:

    سلام. من دانشجوی ارشد ریاضی کاربردی هستم وبرنامه ای که برای پایان نامه ام با متلب نوشته ام متاسفانه ۳_۴ ماه برای اجرا طول می کشد.این برنامه مرحله تعلیم یک پروژه هوش مصنوعی است. تمنا دارم اگر در زوینه افزایش سرعت متلب با فایلهای MEX یا multi_threading اطلاعی دارید یا افراد خبره در این زمینه میشناسید به من کنید.احتیاج فوری به این کمک دارم.یک دنیا ممنون.

    پاسخ دادن
    • eag
      eag says:

      با سلام.

      نکات زیر را در نظر بگیرید.

      ۰) حافظه را مدیریت کنید. در برخی برنامه ها مدت زمان زیادی صرف تخصصی حافظه می شود.
      ۱) نمایش متغیر های اضافی را متوقف نمایید.
      ۲) سعی کنید لوپ های اضافی و زاید برنامهتان را حذف کنید و تا حد ممکن برداری کار کنید.
      ۳) به جای توابع جستجو همانند دستور find، معادل منطقی آنها را استفاده نمایید.
      ۴) با استفاده از امکانات بخش Profiler در متلب برنامه تان را از لحاظ زمانی، آنالیز کنید و bottleneck (گلوگاه) های زمانی را پیدا کرده و رفع نمایید.
      ۵) برنامه در حالت پی کد (pcode)، معمولاً سریعتر از حالت عادی اجرا می شود.
      ۶) از parfor برای اجرای موازی برنامه خود استفاده نمایید. در این حالت باید از پردازنده چند هسته ای مثلا Core2 و … استفاده نمایید. در این حالت می توان تقریباً به تعداد هسته ها برنامه را سریعتر نمود.
      ۷) از MEX برای اجرای بخشی از برنامه خود در سی استفاده نمایید. در این حالت باید برنامه متلب را تا حد زیادی اماده برای این کار نمایید. مثلاً ماتریس ها باید مقدار دهی اولیه شوند (pre-allocation). در این مورد به زودی فیلم جامعی در متلب سایت عرضه خواهد شد. در طی ای مدت سعی کنید از راهنمای متلب استفاده نمایید.

      موفق باشید.
      متلب سایت

      پاسخ دادن
  2. علی
    علی says:

    سلام
    مشکل من زمان زیاد اجرای برناممه وتنها راه رفع اون به نظر من استفاده از فایل mex هستش اما در هیچ جایی نتونستم یه مثال ازش پیدا کنم اگه امکانش هست لطفا منو راهنمایی کنید
    متشکرم

    پاسخ دادن
  3. abbas1982
    abbas1982 says:

    با سلام
    من دارم روی یک پروژه کار میکنم یک مشکل پیش آمده میتونید کمکم کنید
    من خیلی فاکتور برای مقایسه سگمنتهای مختلف در یک تصویر دارم دارم (هم مورفولوژی و هم انواع رنگ )
    اما مشکل خطای out of memory هست
    من اول هر تصویر را به ۳ کانال یعنی ابی وقرمز و سبز تبدیل کردم بعد در هر رنگ دارم مشخصات رو بدست میارم اما فقط میتونم ابی رو انجام بدم بقیه رو که مینیوسم خطا out of memory میده

    پاسخ دادن
  4. نسرین
    نسرین says:

    پیشنهادی که دادید واقعا کارساز هست
    من برنامه ایی نوشته بودم که بدون تعریف ماتریس حدود یک ساعت زمان میبرد اما وقتی از قبل با دستور zeros تعریفش کردم کمتر از ۲ ثانیه همون کارو انجام داد. خودم شگفت زده شدم از این همه اختلاف.

    پاسخ دادن
  5. sara
    sara says:

    سلام
    شما فرمودین از دستور zeros برای اختصاص فضای اولیه استفاده کنیم
    اگه ورودیمون کاراکتر حرف باشه مثه این:
    ASDEFRDF
    باید چجوری فضای اولیه رو اختصاص بدیم؟؟
    برنامه من یک ورودی از کاراکترهای حروف انگلیسی میگیره، اما تعداد این حروف زیاده و ماتریسی که ایجاد میشه ردیفش که یک هست و ستونش باید تعداد این کاراکترها باشه، که نیس و فقط۴۰۹۰ تا کاراکتر اول رو میگیره و سایز ماتریس رو یک در ۴۰۹۰ نشون میده، چکار کنم که کل ورودی رو تو ماتریس ببره؟؟؟؟

    پاسخ دادن
    • مدیر روابط عمومی
      مدیر روابط عمومی says:

      در پاسخ به sara:

      از مکاتبه شما و مطرح کردن این سوال متشکریم.

      «شما می توانید با استفاده از هر یک از دستورهای زیر، آرایه مورد نیاز را، آماده سازی کنید و فضا را برای آن اختصاص دهید:

      a = repmat(‘0’, n, 1);

      a = repmat(‘ ‘, n, 1);

      که در آن، منظور از n تعداد کاراکترهای کل رشته است.

      البته، به نظر می رسد در متن شما، احتمالا کاراکترهای کنترلی (با کد کمتر از ۳۲) وجود دارند که باعث می شود کاراکترها در سطرهای بعدی طبقه بندی شوند.»

      موفق و پیروز باشید.

      پاسخ دادن

ارسال یک پاسخ

در گفتگو ها شرکت کنید.

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *