PDA

View Full Version : استفاده از OpenCL در دلفی. آیا کامپایل فایل cl به شرایط سخت افزاری و سیستم عامل وابسته است؟



SAASTN
شنبه 10 فروردین 1392, 21:48 عصر
افزایش حجم محاسبات باعث بروز مکث تو UI میشه، و اگه این مکث ها زیاد بشن کارایی نرم افزار پائین میاد و یوزر بدبخت به سمت طاسی گام بر میداره! اولین راهکار منتقل کردن محاسبات به یه ترد دیگه است، حالا کاربر متوجه انجام محاسبات تو پشت صحنه نمیشه. اما باز هم مشکل حل نشده، اگر حجم محاسبات باز هم افزایش پیدا کنه و کاربر به نرم افزار فرامینی بده که نیاز به نتیجه محاسبات داشته باشه، بازم باید منتظر بمونه تا محاسبات به پایان برسه. پس مسئله اصلی پائین آوردن زمان کلی محاسباته. راهکار بعدی استفاده از تردهای موازی هست، به این ترتیب در خوشبینانه ترین حالت می تونیم زمان محاسبات رو به میزان 1 تقیسم بر تعداد هسته هاپائین بیاریم. یعنی مثلا یه پردازش 20 ثانیه ای روی یه CPU کواد تو 5 ثانیه انجام میشه. اما هنوز یه پرداش یک ساعته به 15 دقیقه زمان احتیاج داره. اینجاست که باید به فکر استفاده از حداکثر توان سیستم باشیم. مثلا پردازنده های موجود در GPU.
یکی از راههای استفاده از این پردازنده ها OpenCL (http://www.khronos.org/opencl/)هست. با استفاده از این فریمورک میشه از تمام پردازنده های موجود در سیستم بصورت موازی برای انجام محاسبات استفاده کرد. راهکار موجود برای استفاده از OpenCL در دلفی پروژه delphi-opencl (https://code.google.com/p/delphi-opencl/) هست که یک لایه از کلاس های دلفی، بین نرم افزار و API ایجاد میکنه.

من از اینجا (https://code.google.com/p/delphi-opencl/downloads/detail?name=OpenCL_std_and_oop.rar) کتابخونه ها و مثالها رو دانلود کردم، اما تو همون گام اول برای اجرای Example1 به مشکل برخوردم. روی سیستم من بعد از اجرای این خط:
Kernel := SimpleProgram.CreateKernel('somekernel');

مقدار FStatus شیئ Kernel به CL_INVALID_PROGRAM_EXECUTABLE تغییر می کرد. بعد از پیگیریهای فراوان:گیج: متوجه شدم که مشکل اصلی مربوط به خط زیر در یونیت DelphiCL هست:
FStatus := clBuildProgram(FProgram,0,nil,Options,nil,nil);

در واقع مشکل اینجا بود که کامپایل کد cl روی سیستم من با موفقیت انجام نمیشد. در نهایت با استفاده از این کد تونستم مشکل رو پیدا کنم:
Res := clGetProgramBuildInfo(SimpleProgram.Program_, FDevice_id, CL_PROGRAM_BUILD_LOG, 1024, val, @valSize);

لاگ بدست آمده بدین شرحه:
<program source>:4:12: error: call to 'pown' is ambiguous
dst[id] = pown(src[id],4);
^~~~
<built-in>:6128:24: note: candidate function
float __OVERLOADABLE__ pown(float a, int b);
^
<built-in>:3495:25: note: candidate function
double __OVERLOADABLE__ pown(double a, int b);
^


خوب این مشکل با تغییر نوع پارامتر های somekernel از int به float حل میشه. اما موضوع یه مقدار عجیبه، در واقع نمیشه فرض کرد که کسی که این کتابخونه رو برای دلفی آماده کرده اولین مثالشو از نظر نحوی! تست نکرده باشه. من همین مثال رو روی یه سیستم دیگه اجرا کردم و در کمال ناباوری دیدم که کد بدون هیچ مشکلی نتایج مورد نظر رو تولید کرد. این موضوع یه مقدار پرتابل بودن این فریمورک رو زیر سوال میبره. در واقع ترس من از اینه که کدی که آماده میشه روی سیستم من جواب بگیره اما موقع اجرا روی سیستم کاربر با مشکل مواجه بشه، و سوال اینه که کامپایل کد cl به چه پارامترهایی وابسته است؟ چطور میشه مطمئن شد که کرنل های توسعه داده شده روی یک پی سی رو بقیه پی سی ها هم درست عمل کنند. و در نهایت سوال اصلی اینکه اصلا برای شرایطی که اول پست توضیح دادم OpenCL راهکار مناسبی هست؟:متفکر:

BORHAN TEC
یک شنبه 11 فروردین 1392, 03:29 صبح
سلام
یک سوالی برای من پیش آمده که من این رو از بین توضیحات شما متوجه نشدم و اون هم اینه که یعنی شما در یک کد مشخص در یک سیستم خطای زمان کامپایل داشته اید و در یک سیستم دیگر برای همان کد خطای زمان کامپایل نداشته اید؟ و یا اینکه یک فایل اجرایی تولید شده مشخص در یک سیستم (که در آن از OpenCL استفاده شده) بدون مشکل کار می کند و در یک سیستم دیگر کار نمی کند؟ میشه این موارد رو واضح تر توضیح دهید؟ :متفکر:

SAASTN
یک شنبه 11 فروردین 1392, 09:25 صبح
کد سمت دلفی هیچ خطایی نداره. مشکل توی کد سمت OpenCL هست. کد OpenCL هم در زمان اجرا لود و کامپایل میشه. یعنی اگه فایل متنی حاوی کد OpenCL رو تغییر بدیم، بدون نیاز به کامپایل دوباره کد دلفی، رفتار برنامه تغییر می کنه. حالا مشکل اینجاست که یه کد OpenCL مشخص روی یه سیستم بدون مشکل کامپایل میشه و خروجی مورد انتظار رو تولید میکنه اما رو یه سیستم دیگه همون کد خروجی تولید نمی کنه، علتش هم همون ابهامی هست که توی لاگ پست قبلی گداشتم. چیزی که مشخصه اینه که تفسیر نحوی OpenCL توی دوتا سیستم متفاوته، یعنی توی سیستم من پارسر OpenCL نتونسته تشخیص بده که int رو به float تبدیل کنه یا double. اما توی یه سیستم دیگه این ابهام وجود نداشته. حالا یا اصلا دو تا overload از pown وجود نداشته یا خود پارسر یه پیشفرضی رو انتخاب کرده.

BORHAN TEC
یک شنبه 11 فروردین 1392, 10:36 صبح
بنده این نکته را متوجه شدم که شما از آخرین نسخه این کتابخانه استفاده نکرده اید. آن فایل فشرده ای که شما دانلود کرده اید مربوط به "Dec 10, 2011" است که آخرین تغییرات این کتابخانه در آن اضافه نشده است. معمولاً در اینگونه کتابخانه ها فراموش می کنند که این فایل ها ی فشرده را بروز رسانی کنند و کاربرانی که مراجعه می کنند فکر می کنند که بعد از آن این پروژه ها توسعه داده نشده اند(مثالی از این دست را می توان در کتابخانه DsPack و غیره هم دید). همیشه سعی کنید که جدید ترین نسخه را از Repository دانلود کنید و از آن استفاده کنید. بعد از این کار اگر باز هم مشکل داشتید بیان کنید تا برای حل مشکل بتوانیم با هم همفکری کنیم.
در ضمن اون باگی هم که در پست 3 بهش اشاره کردید (و اگر من درست متوجه منظورتون شده باشم) در "Dec 11, 2011" حل شده است(یعنی یک روز بعد از عرضه آن فایل فشرده!):
https://code.google.com/p/delphi-opencl/source/detail?r=25

SAASTN
یک شنبه 11 فروردین 1392, 13:05 عصر
شاهین جان فکر کنم بحث داره به بیراهه میره. مشکل من باگ نیست. سوال من اینه که کسی از این فریمورک استفاده تجاری کرده و آیا این فریمورک حقیقتا پرتابل و قابل اعتماده، یا اینکه رفتار متفاوت روی سیستم های مختلف طبیعیه؟ یا شاید باید مسائل خاصی رو موقع استفاده مدنظر قرار بدیم. نتیجه کار قراره روی چند هزار سیستم اجرا بشه و شرایط تحت کنترل نیست. از طرفی هزینه سوئیچ کردن محاسبات روی این فریمورک برای تیم زیاده و نمیشه هر روز روش محاسبه رو عوض کرد. من دنبال یه راهکار قابل اعتماد برای انجام حجم بالای محاسبات اعشاری و برداری هستم و می خوام بدونم که آیا OpenCL انتخاب درستی هست یا نه؟

BORHAN TEC
یک شنبه 11 فروردین 1392, 13:22 عصر
سوال من اینه که کسی از این فریمورک استفاده تجاری کرده و آیا این فریمورک حقیقتا پرتابل و قابل اعتماده، یا اینکه رفتار متفاوت روی سیستم های مختلف طبیعیه؟
اوکی، واقعیتش اینه که نمیدونم که چقدر قابل اعتماد هست؟! :اشتباه: در حال حاضر برای اینکه بخواهی این مطلب رو متوجه بشی شاید بهترین راه حل این باشه که یک فایل اجرایی رو در همینجا قرار بدی و افراد مختلف روی سیستم های مختلف برنامه را تست کنند و آنرا گزارش کنند. این موضوع (پردازش های خیلی سنگین) برای من هم واقعاً مهم است. اگر فایل اجرایی رو در همین تاپیک قرار بدی میتونیم اطلاع رسانی کنیم(مثلاً در امضامون قرار بدیم) تا دوستان در این تست شرکت کنند. به نظر من اگر این تست توسط افراد زیادی صورت بگیره همه چیز مشخص میشه. نظرت چیه؟

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

در ضمن در مورد اینکه این مسائل پیش آمده طبیعی است یا خیر بهتره به نوسنده این کتابخانه ایمیل بزنی و ازش بپرسی. ایمیلش اول یونیت های مربوطه اومده(فکر می کنم این سریعترین روش برای متوجه شدن این موضوع باشه):
muxamed13@ukr.net

SAASTN
یک شنبه 11 فروردین 1392, 18:21 عصر
فکر نمی کنم اینجا تست کردنش هم نتیجه خوبی بده. بهترین روش همون تست در غالب یه پک آپدیته که اونم مسائل خودش رو داره. با این حال اگه کسی تجربه ای در این مورد داره ممنون میشم اینجا گفته بشه.

یوسف زالی
دوشنبه 12 فروردین 1392, 15:15 عصر
سلام.
خیلی خوشحال شدم که استاد ما هنوز در سایت هستند.
می شه در خصوص نوع محاسبات یا الگوریتمش بگید؟
ممکنه بشه با روشهای ابتکاری صورت مساله رو تغییر داد.

MSK
دوشنبه 12 فروردین 1392, 22:52 عصر
با اجازه دوستان من هم اینجا یه نظری بدم:
مشکل مشخصا این بوده که روی سیستم شما کامپایلر opencl (که پیاده کننده درایور opencl اونو تولید میکنه؛ مثلا nvidia یا intel یا ATI) نتونسته تصمیم بگیره float رو انتخاب کنه یا double رو.
من فکر می‌کنم چند تا احتمال مختلف وجود داره که چرا روی سیستم دیگه این مشکل بوجود نیومده.

۱- شاید سیستم دیگه کلاً double رو ساپرت نمی‌کرده. خیلی از gpu ها اینطور اند.
۲- شاید پیاده ساز کامپایلر opencl توی سیستم های دیگه تصمیم گرفته که یکی رو ترجیح بده.

حالا سوال اول شما راجع به پورتیبل بودن برنامه های opencl بوده. هدف ایجاد opencl پورتیبل بودن برنامه‌هاش بوده.
opencl یه استاندارد ه و شما دارید روی سیستم های مختلف پیاده سازی های مختلف رو می‌بینید. و مشکل از اینجا ایجاد میشه. چون پیاده سازی ها ۱۰۰٪ کامل و بی عیب و نقص نیستند و بعد از اون استاندارد همه ی جزئیات رو توضیح نمیده، پس تو اون جزئیات، پیاده سازی ها دستشون بازه که هرجور می‌خوان عمل کنند. شاید مشکلی که شما بهش برخوردید از این نوع مشکلات بوده.
اما نکته ای که شما باید بهش توجه کنید اینه که شما اگه یه برنامه ی ۴ خطی هم داشته باشید که فقط کارش خوندن - نوشتن فایل هاست شاید به یه سیستمی بر بخورید که توش مشکل پیدا کنه. مثلا یه آنتی‌ویروس دیوانه داره که هرچی رو که نمیشناسه میگه وبروسه! توی همین مثال شما وقتی دیدید با تبدیل کردن یکی از پارامتر ها به double مشکل حل میشه، این کار رو کردید و حالا میتونید بگید که توی ۹۹٪ سیستم ها اجرا میشه. اگه بعدا به مشکل برخوردید دباره به سراغش میرید و سعی میکنید که حلش کنید. اما درمورد پورتیبل بودن برنامه ها نگرانی شما بی مورده. هدف، پورتیبل بودن بوده.

اما در مورد سوال دومتون که آیا این راه حل مناسبی ه با نه برای برنامه های با محاسبات زیاد، کلا مسئله فرق می‌کنه. حتی از نظر پورتیبل بودن!!
مشکل اینجاست که پیاده سازی opencl یک سیستم، مختص اون سیستم ه و شما نمی‌تونید خود opencl رو همراه برنامه‌تون (مثلا مثل یه dll) توزیع کنید؛ و کاربر باید خودش این کار رو برای سیستم خودش بطور جدا انجام داده باشه. توزیع opencl روی پلتفرمهای nvidia, ati, intel و سیستم عامل های windows, linux, *bsd, mac همه متفاوت اند و باید بطور اختصاصی نصب بشند. اگه سیستم های mobile رو هم به لیست اضافه کنید وضعیت فاجعه‌بار میشه (رو خیلی از پلتفرم ها اصلا پیاده سازی مناسب وجود نداره)
اگه خودتون رو مثلا محدود کرده باشید به پلتفرم windows و nvidia خیلی از مشکلات حل میشه، اما باز هم نه بطور کلی. در هرصورت به نظر میرسه opencl برای نوشتن برنامه های عمومی دسکتاپ مثل word processor ها خیلی مناسب نیست (حداقل فعلا) و راه حل اصلی واقعا همون مولتی ترید هست. رویکرد تکنولوژی هم به همین سمت‌ه. تعداد هسته های cpu ها هرروز زیادتر میشه.
اما از طرف دیگه باید دید اصلا opencl برای چه چیزهایی مناسبه. opencl روی سیستمهایی داره اجرا میشه که مبتنی بر مفهوم SIMD (http://en.wikipedia.org/wiki/SIMD) هست. یعنی مناسب دسته ی خاصی از محاسبات ریاضی، مثل محاسبات ماتریسی و گرافیکی‌ه. نوشتن برنامه هایی که برای اینجور محاسبات، مناسب نیستند (مثل برنامه هایی که نیازمند تصمیم‌گیری منطقی یا if هستند) مزیت زیادی روی opencl نداره. برعکس فقط به پیچیدگی برنامه اضافه می‌کنه.
اگه شما برنامه ای دارید که مشقول رد و بدل اطلاعات زیادی روی شبکه هست و بخاطر اینه که خیلی زمان‌بره، احتمالا opencl برای شما نیست. اما اگه برنامه‌ی شما مشقول محاسبات علمی هست که در اون حجم زیادی از دیتا با یک الگوریتم ساده باید پروسس بشه، اون وقت شما دنبال opencl میگردید! :لبخند:

SAASTN
چهارشنبه 14 فروردین 1392, 11:19 صبح
ممنون از زمانی که گذاشتین و شرمنده که دیر جواب میدم.

می شه در خصوص نوع محاسبات یا الگوریتمش بگید؟
ممکنه بشه با روشهای ابتکاری صورت مساله رو تغییر داد.
همون طور که قبلا گفتم محاسبات بیشتر از نوع اعشاری و در قالب برداری دوبعدی و سه بعدی هستن. بعضی از محاسبات هم فقط در قالب محاسبات ریاضی تعیین شده برای پیدا کردن یه سری مقادیر مشخص هست، از نتیجه این محاسبات برای پیدا کردن حالات بحرانی و تصمیم گیری های بعدی استفاده میشه. اما همیشه برای بهینه کردن الگوریتم ها راهی هست، در واقع باید بگم بیشتر وقت من و بقیه همکارام به همین کار میگذره و از اونجایی که تعداد مسئله ها زیاده برای بررسی هرکدومشون باید یه تاپیک جداگونه ایجاد کنیم. اما برای اینکه فعلا بحث پیش بره به عنوان مثال یکی از الگوریتم هایی که تعداد فراخونیش توی برنامه بالاست، تابع بررسی قرار داشتن یه نقطه توی یه چند ضلعی هست. الگوریتمی که در حال حاضر ازش استفاده می کنیم Ray-Casting (http://alienryderflex.com/polygon/) هست. چند ضلعی ها می تونن محدب باشن یا مقعر، ممکنه نقاط اضافی روی اضلاع وجود داشته باشه، کنترلی روی راستگرد یا چپگرد بودن اونها نیست، بازه مختصاتی اونها به رنج مشخصی محدود نمیشه و پیش بینی ای هم نسبت به نتیجه وجود نداره، یعنی تعداد حالاتی که پاسخ تابع True هست اختلاف معناداری با تعداد حالات False نداره! :عصبانی++:


حالا سوال اول شما راجع به پورتیبل بودن برنامه های opencl بوده. هدف ایجاد opencl پورتیبل بودن برنامه‌هاش بوده.
احسنت! گیرم همینه. و علت این گیر هم همون چیزیه که خودت خیلی خوب بیان کردی:

opencl یه استاندارد ه و شما دارید روی سیستم های مختلف پیاده سازی های مختلف رو می‌بینید. و مشکل از اینجا ایجاد میشه. چون پیاده سازی ها ۱۰۰٪ کامل و بی عیب و نقص نیستند و بعد از اون استاندارد همه ی جزئیات رو توضیح نمیده، پس تو اون جزئیات، پیاده سازی ها دستشون بازه که هرجور می‌خوان عمل کنند. شاید مشکلی که شما بهش برخوردید از این نوع مشکلات بوده.
خود این مطلب تحدیدی برای پرتابل بودن برنامه نیست؟ از اونجایی که کارکرد نرم افزار محاسباتی هست به حداقل هایی از سخت افزار نیاز داره، پس فعلا میشه موبایل و تبلت رو از لیست حذف کرد، هر چند با روندی که بازار سخت افزار داره طی می کنه شاید تا چند سال دیگه نشه همچین فرضی کرد. از طرفی کاربر نرم افزار هموطنان عزیزمون هستن که با توجه به شرایط کپی رایت حاکم بر کشور ترجیحشون سیستم عامل ویندوزه. شاید الان برای فکر کردن به شرایطی که این فرض نقض میشه یکم زود باشه. اما در مورد سخت افزار PC نمیشه فرض خاصی کرد. به عنوان مثال استفاده از CUDA قبلا به همین دلیل محدود بودن به nvidia حذف شده. (این حذف به این دلیل کار درستی بوده؟:متفکر:)
حالا باتوجه به این که امکان توزیع OpenCL هم وجود نداره راهکار چیه؟ آیا نگارش های جامع و شاید حداقلی وجود داره که بتونیم به عنوان بیس کار قرار بدیم؟

opencl روی سیستمهایی داره اجرا میشه که مبتنی بر مفهوم SIMD هست. یعنی مناسب دسته ی خاصی از محاسبات ریاضی، مثل محاسبات ماتریسی و گرافیکی‌ه.
در مورد صورت مسئله، یه مورد رو اول همین پست گفتم. کلیت کار رو نمیشه در قالب SIMD بیان کرد. ولی شاید بشه اون رو به تکه های خوردتری که از این قالب تبعیت کنن تقسیم کرد. در واقع این همون کاری هست که ما می خوایم انجام بدیم. یعنی روش های برنامه نویسی رو به ترتیبی تغییر بدیم که بخش های همنوع از محاسبات از هم تفکیک بشن. اما تشخیص مرز بین محاسبات عدی و تصمیمات منطقی یه مقدار سخته. این مسئله رو هم میشه توی همون مثال دید که توی اون محاسبات اعشاری با تصمیمات منطقی به نوعی تلفیق شدن. به عنوان مثال خود استفاده از حلقه for به تنهایی نیاز به انجام تصمیم گیری داره. تجربه اندک خودمم همین بوده که احتمالا استفاده از for هم خودش میتونه performance رو تا حد زیادی پائین بیاره. (درسته؟) اما اگه واقعا بخوایم محاسبات رو تا حد الگوریتم های کاملا خطی پائین بیاریم باز شرایط تغییر می کنه. اون موقع باید باید به فکر فراید آماده کردن داده مناسب برای این سبک محاسبه و حجم دیتا باشیم. واقعیت اینه که ما عموما با تعداد فراخونی بالا و داده نه بسیار بزرگ برای هر فراخونی طرفیم. حالا باید مراقب باشیم که سربار ناشی از سرهم کردن این داده های پراکنده به نسبت سرعت پردازشی کارت گرافیک که خودش خیلی پائین تر از هسته های CPU هست، مفیده یا نه؟
مسئله دیگه ای هم که من بهش برخورد کردم و به نوعی با این تاپیک مرتبطه مسئله قضیه TDR (http://msdn.microsoft.com/en-us/library/windows/hardware/gg487368.aspx) هست. خوب من به هیچ عنوان نمیتونم تضمین کنم که محاسبات تو پیش فرض 2 ثانیه به نتیجه برسه. از طرفی نمی دونم که غیر فعال کردن این سیستم هم شرعا چه صورتی داره؟ تا جایی که خوندم این قضیه توی بازی ها خیلی رایجه اما اون دسته از نرم افزار ها به نوعی فرض Multi-Task بودن رو نادیده می گیرن. نادیده گرفتن این فرض برای نرم افزار ما بدون شک یه پوئن منفی خواهد بود!:لبخند:

یوسف زالی
چهارشنبه 14 فروردین 1392, 14:12 عصر
چند مدت قبل یک پروژه شبیهش داشتم. البته در اون چند ضلعی ها ملزم بودند که خود را قطع نکنند. البته چندان هم فرقی ایجاد نمی کرد.
روشی که اون موقع من استفاده کردم استفاده از رنگ کردن با توابع FLoodFill در نقطه ای داخل گراف بود و تست اینکه رنگ پشت نقطه ی من الان رنگ شد یا نه.
شاید در مقیاس های بالا این روش کندتر باشه، تست نکردم.
در واقع داشتن یک نقطه درون گراف کمک بزرگی به تست باقی نقاط می کرد.
لزومی به نمایش گرافیکی رنگ شدن هم نیست. می شه این کار رو با بیت مپ ها در حافظه انجام داد که سریعتر باشه.

SAASTN
پنج شنبه 15 فروردین 1392, 02:58 صبح
روشی که اون موقع من استفاده کردم استفاده از رنگ کردن با توابع FLoodFill در نقطه ای داخل گراف بود و تست اینکه رنگ پشت نقطه ی من الان رنگ شد یا نه.
حل این مسئله تو فضای رستر برای ما امکان پذیر نیست. به علت فضای گسترده و دقت مورد نیاز، حجم داده رستر می تونه به سمت بینهایت میل کنه. به عنوان مثال ممکنه در یه کال تابع به دقت 1e-10 میلیمتر نیاز باشه و درعین حال چند ضلعی محدوده ای به ابعاد تقریبی 10*10 متر رو پوشش بده. این یعنی حدودا 1e28 پیکسل!:متعجب: ترسیم و رنگ زدن چند ضلعی(البته تو رم) تو همچین فضایی میتونه زمان زیادی ببره. از طرفی همون چند ضلعی حد اکثر از 100 راس تشکیل شده و با پردازش وکتور میشه با دقت های بالاتری در زمان خیلی کمتر به جواب مورد نظر رسید. برای این کار هم روش های متفاوتی وجود داره که هر کدوم در شرایط مختلفی می تونن بهینه باشن. اینجا (http://erich.realtimerendering.com/ptinpoly/)یه مقایسه بین چند نمونه از الگوریتم های مطرح انجام شده.

MSK
پنج شنبه 29 فروردین 1392, 17:27 عصر
در مورد نیازمندی های برنامتون توضیحات خیلی خوبی دادید که با توجه به این توضیحاتتون من فکر میکنم که تصمیم به استفاده از opencl تصمیم بجایی است. این در مورد سوال در مورد cuda.
اما نکته ای که باید در نظر بگیرید این هست که gpu هم مانند cpu قادر به تصمیم گیری (یا همون پرش شرطی) هست، اما به محض اینکه شما روی کارت گرافیک سراغ پرش های شرطی برید از افت پرفرمنس سرخورده خواهید شد. به همین دلیل تکنیک های متعددی برای جلوگیری از اینطور پرش های شرطی طراحی شده، که اگه سرچ کنید پیدا می کنید.
در مورد for باید بگم که اگه تعداد دفعاتی که قراره این حلقه اجرا بشه توسط compiler قابل پیشبینی باشه (در زمان اجرا، نه کامپایل) در این صورت افت کارایی ای نخواهید داشت. اما اگه شرط خروج از حلقه، بطور مشخص تعداد دفعات اجرای حلقه رو مشخص نکنه، for فقط شکل دیگه ای از while ه؛ و این هم مشخصا یعنی پرش شرطی و افت کارایی.
اما در مورد پرش شرطی باید بدونید که cpu به مراتب بیشتر بهینه شده برای مواجهه با این مسئله و اگه الگوریتم شما شدیدا وابسته به این انشعابات شرطی هست، شاید ببینید که اجرای اون روی یه پردازشگر core i7 منتقی تر از اجرای اون روی gpu باشه. مخصوصا اگه نیاز به مبادله حجم زیادی از داده بین رم سیستم و کارت گرافیکی داشته باشید. باید برای اینجور مسایل تست کنید و ببینید بهترین انتخاب کدومه.

در هر صورت توجه داشته باشید که opencl روی cpu هم قابلیت اجرا دارد و کد تولید شده توسط آن روی cpu هم معمولا بهینه تر از کامپایلر های معمولی هست. و این جدا از این مسئله است که opencl مشکل موازی سازی و overhead ایجاد thread های سیستمی را هم از بین می برد. در نتیجه می‌توان گفت برای مسئله شما قطعا بهترین راه حل همین opencl هست.

اما در مورد دو مشکل دیگه؛ یکی tdr و دیگری توزیع opencl.
مشکل tdr به شما صدمه ای نمی زند، به این دلیل که سیستم عامل به دنبال برنامه هایی می گردد که برای مدت طولانی صفحه نمایش را در حالت freeze قرار می دهند. برنامه شما دارای چنین مشکلی نیست. برای آنکه خود برنامه شما هم responsive باقی بماند کافی هست محاسبات opencl را به یک نخ سیستمی دیگر منتقل کنید.
در مورد توضیع opencl هم با توجه به فرض های شما فقط سه توضیع باقی می‌ماند: intel, nvidia و ati . هر سه توضیع رو به همراه برنامه تان ارایه دهید.

موفق باشید.