PDA

View Full Version : برنامه نویسی موازی در C++ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ای



sibooy
دوشنبه 28 مرداد 1392, 13:12 عصر
دوستان سلام
در این تاپیک می خوام از همه دعوت کنم که اگر مطلبی درمورد برنامه نویسی موازی در C یا C++‎‎‎‎‎‎‎‎‎‎ بلدین اینجا بذارین.
من خودم با CUDA و OpenMP کار کردم. هرچه رو هم یاد گرفتم اینجا میذارم. شما هم هرچه می دنید دریغ نکنید

اول OepenMP:
یک کتابخانه ست که به C و C++‎‎‎‎‎‎‎‎‎‎ اضافه می شه و می تونید با اون برنامه هاتون رو موازی کنید بطوریکه اگر چندتا پردازنده و یا یه پردازنده چند هسته ای داشته باشید همه پردازنده ها رو برای پردازش بکار بگیره.
نحوه راه اندازیش رو Visual Studio 2010 توی این تاپیک در پست های پایین و همچنین توی این لینک گذاشتم
http://barnamenevis.org/showthread.php?395000-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%85%D9%88%D8%A7%D8%B2%DB%8C-%D8%AF%D8%B1-vs-c-2010-%D8%A8%D9%87-%D9%88%D8%B3%DB%8C%D9%84%D9%87-OPENMP
http://barnamenevis.org/showthread.php?413514-%D9%85%D9%88%D8%A7%D8%B2%DB%8C-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%AD%D9%84%D9%82%D9%87-%D9%87%D8%A7%DB%8C-%D8%AA%D9%88-%D8%AF%D8%B1-%D8%AA%D9%88-%D8%AF%D8%B1-OpenMP-%D9%86%D8%B3%D8%AE%D9%87-2.0
دوم CUDA:
یک گسترش کوچیک از C هست که بازم بصورت کتابخانه به C++‎‎‎‎‎‎‎‎‎‎ اضافه می شه. برای استفاده از اون باید از محیط visual studio 2005 یا 2008 یا 2010 استفاده کنید. از CUDA برای اجرای برنامه روی پردازنده گرافیکی استفاده می شه. یعنی شما می تونید محاسباتتون رو بجای CPU روی پردازنده گرافیکی تون اجرا کنید.

نحوه راه اندازیش روی visual studio C++‎‎‎‎‎‎‎‎‎‎2010 رو در پست های پایین گذاشتم همچمین توی این لینکم هست.
http://barnamenevis.org/showthread.php?377875-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-cuda-%D8%AF%D8%B1-VC-(-%DA%A9%D9%88%D8%AF%D8%A7-%D8%AF%D8%B1-%D9%88%DB%8C%DA%98%D9%88%D8%A7%D9%84-%D8%B3%DB%8C-)
یه برنامه کاربرردی کوچک هم نوشتم که از این لینک می تونید ببینید البته توی پست های پایین همین تاپیک هم گذاشتم.
http://barnamenevis.org/showthread.php?393192-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-CUDA-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-(vs-c-2010)-%D9%88%DB%8C%DA%98%D9%88%D8%A7%D9%84-%D8%A7%D8%B3%D8%AA%D9%88%D8%AF%DB%8C%D9%88-c
شما هم هرچه از برنامه نویسی موازی بلدید بگید که ما و بقیه دوستان استفاده کنیم.
parallel programming


----------------------------------------------
زکات علم نشر آن است. علی(ع)

sibooy
دوشنبه 28 مرداد 1392, 13:14 عصر
برنامه نویسی موازی با OPENMP

هنوز ابتدای راهم اما بلاخره بعد از مدت ها تونستم راه اندازی OPENMP رو در ویژوال استودیو 2010 (visual studio 2010) رو پیدا کنم چون هرچه هم کتابخانه omp.h رو include می کردم فایده نداشت.
این مختصر رو اینجا می نویسم امیدوارم اگر کسی هم مثل من مشکلی براش پیش اومد بتونه از این راهنمایی استفاده کنه.
برای راه اندازی ابتدا یک پروژه C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎ ایجاد می کنیم البته از نوع win32 consol application توجه داشته باشید از پنجره application setting علامت تیک perecompiled heder رو بردارید (یعنی این گزینه نباید انتخاب شده باشه) بعد ok کنید.
قسمت اصل کاری:
در قسمت solution explorer روی پروژه راست کلیک کنید بعد این مسیر رو برید
peroperties-> configuration peroperties-> c/C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎ -> language
حالا از فریم کناری گزینه openmp support رو yes می کنیم بعدم applay و ok می کنیم.
حالا دیگه پروژه شما OPENMP رو پشتیبانی می کنه.
بعد یک فایل .cpp هم برای برنامه نویسی ایجاد می کنیم و داخلش باید برای استفاده از openmp فایل omp.h رو include کنیم.
نمی دونم چرا این تیکه اصل کاری رو فراموش کرده بودم بنویسم:عصبانی++::عصبانی++: از همه دوستانی که اومدن اینجا و دست خالی برگشتم عذر می خوام:خجالت::خجالت:
یه لینک بسیار بدرد بخور هم پیدا کردم که دستورات openmp رو خیلی خوب با مثال توضیح میده. به علت رعایت قانون کپی رایت متن مطلب رو اینجا نمی نویسم اما لینکش رو میگذارم(درست برو بچه های ماهنامه شبکه درد نکنه:تشویق:)
http://www.shabakeh-mag.com/article.aspx?id=1004072 (http://www.shabakeh-mag.com/article.aspx?id=1004072)
اینم لینک یه راهنمای خارجی که باز هم دستورات رو خیلی خوب و همراه مثال توضیح داده
http://bisqwit.iki.fi/story/howto/openmp/ (http://bisqwit.iki.fi/story/howto/openmp/)
اینم یه نمونه کد کوتاه برای اینکه ببنید برنامه بصورت موازی اجرا می شه یا نه.
خروجی برنامه باید چاپ اعداد یک تا ده بصورت نامرتب باشه (چون هر عدد توسط یک thread بصورت موازی با threadهای دیگه چاپ میشه و ممکنه threadها پشت سر هم اجرا نشن(این خاصیت برنامه نویسی موازی هست اگر اعداد مرتب چاپ شد به موازی سازی تون شک کنید)
در این برنامه چون پردازنده من دو هسته ای هست برنامه برام دوتا thread درست می کنه و همه دستورات چاپ رو دوبار برام چاپ می کنه و اعداد داخل حلقه رو هم قاطی دستورات چاپ دیگه چاپ می کنه:) !!!!!!
باید از دستورات هماهنگ سازی استفاده کرد که من هنوز باهاشون کار نکردم. :متفکر:
انشاءالله که خدا کمک کنه بیشتر یاد بگیرم اینجا هم بیشتر درباره OPENMP و برنامه نویسی موازی با اون می نویسم.

اگر دوستان مطلبی بلد هستن به من هم یاد بدن جای دوری نمیره (خدا یک در دنیا صد در آخرت عوض خیر بهتون بده آمییییین:خجالت:)

اینم اون کد که بهتون گفتم
#include<omp.h>
#include<stdio.h>
#include<conio.h>
long int i,j,a,k;
int main(int argc, char* argv[])
{omp_set_num_threads(4);
omp_set_dynamic(true);
omp_set_nested(true);


#pragma omp parallel shared(i,j,a) num_threads(4)

{
k=omp_get_num_procs();
printf("number of processor= %d \n",k);
k=omp_in_parallel();
printf("if program in paralle=1 or serial=0 ?? %d \n",k);
k=omp_get_max_threads();
printf("muaximum number of thread= %d \n",k);
k=omp_get_num_threads();
printf("number of threads= %d \n",k);
k=omp_get_thread_num();
printf("thread number is= %d \n",k);

#pragma omp for
for(j=0;j<10;j++)
printf("%d",j);

}

j=0;
getch();
return 0;
}

خدا خیر بده هرکسی این داکیومنتو درست کرده (از لینک زیر دانلود کیند)
http://www.google.com/url?sa=t&rct=j&q=openmp+supprt+change+yes&source=web&cd=10&cad=rja&ved=0CIIBEBYwCQ&url=http%3A%2F%2Fwww.ee.ryerson.ca%2F~courses%2Fee 8218%2FOpenMPmanual.doc&ei=U3h2UaiRGJTe7Abc_oD4Dw&usg=AFQjCNELSQbYIfFYBKz1Tyil7JjwyK1FNg&bvm=bv.45512109,d.ZWU
اگر میخواید برنامه نویسی بسیار موازی با cuda رو هم تازه شروع کنید این دو لینک خیلی به دردتون خواهد خورد
برای نصب و راه اندازی cuda روی ویژوال استودیو C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎ به لینک زیر برید
http://barnamenevis.org/showthread.php?377875-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-cuda-%D8%AF%D8%B1-VC-(-%DA%A9%D9%88%D8%AF%D8%A7-%D8%AF%D8%B1-%D9%88%DB%8C%DA%98%D9%88%D8%A7%D9%84-%D8%B3%DB%8C-)&highlight=cuda
و برای آشنایی با نحوه نوشتن یک برنامه موازی کوتاه در cuda به لینک زیر برید
http://barnamenevis.org/showthread.php?393192-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-CUDA-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-(vs-c-2010)-%D9%88%DB%8C%DA%98%D9%88%D8%A7%D9%84-%D8%A7%D8%B3%D8%AA%D9%88%D8%AF%DB%8C%D9%88-c&highlight=cuda
درپناه حق تعالی باشید

----------------------------------------------
زکات علم نشر آن است. علی(ع)

sibooy
دوشنبه 28 مرداد 1392, 13:15 عصر
موازی سازی حلقه های تو در تو در OpenMP نسخه 2.0
با توجه به اینکه نسخه 2010 ویژوال استودیو C++‎‎‎‎‎‎‎ از کتابخانه OpenMP نسخه 2.0 فقط خارجی ترین حلقه رو می تونه موازی کنه. ولی یه راه هست.
***(در نسخه 3.0 و بعد تر با اضافه کردن عبارت colaps(i) به عبارت pragma omp for می شه عمق موازی سازی رو مشخص کرد. بجای i باید عدد بذاریم مثلا 3. یعنی تا عمق 3 حلقه های تو در تو رو موازی اجرا کنه)****
طریقه ایجاد حلقه تو در تو در OpenMP نسخه 2.0 (از نسخه 3.0 به بعد حلقه های تو در تو پشتیبانی می شن.)
یک راه جالب توی کتاب OpenMP پیدا کردم دوتا حلقه تو در تو رو می شه به یکی از این دو شیوه موازی کرد نمی دونم حلقه سوم رو هم با همین شیوه می شه موازی کرد یا نه اما همینم غنیمته.
شیوه اول:

#pragma omp parallel default (shared)
{
#pragma omp for
for(i=0;i<n;i++)
{
#pragma omp parallel shared(i,n)
{
#pragma omp for
for(j=0;j<n;j++)
work(i,j);
}
}
}

شیوه دوم:

#pragma omp parallel default (shared)
{
#pragma omp for
for(i=0;i<n;i++)
work1(i,n);
}

void work1(int 1, int n)
{
int j;
#pragma omp for
for(j=0;j<n;j++)
work2(i,j);
}



----------------------------------------------
زکات علم نشر آن است. علی(ع)

sibooy
دوشنبه 28 مرداد 1392, 13:16 عصر
آموزش مراحل نصب و راه اندازی cuda در ویژوال استودیو 2010
برای نصب کودا لازمه که اول درایور های کودا رو از سایت انویدیا دانلود کنید
اگر از ایران می خواید وارد سایت انویدیا بشید حتما باید یه فیلتر شکن قوی داشته باشید که سایت انویدیا نفهمه شما از ایران دارید وصل می شید (چون سایت انویدیا اصلا به ایران خدمات نمیده و ما رو جزء لیست تحریمش قرار داده)
پس اول شد فیلتر شکن
بعدم باید درایورهای انویدیا رو دانلود کنید
بعدم باید cuda toolkit رو دانلود کنید و نصب کنید
از این لینک
http://developer.nvidia.com/cuda-downloads
بعدم cuda sdk رو دانلود کنید و نصب کنید (از همون لینک بالا)
البته اگه نسخه 5 از cuda toolkit رو دانلود کنید sdk هم همراهشه.

البته من که دانلود کردم sdk همراهش نبود نمی دونم چرا توی سایتش نوشته همراهشه.

ولی توی نسخه های قدیمی تر toolkit و sdk از هم دیگه جدان
مثلا من خودم از نسخه 4.2 استفاده می کنم که هم toolkit و هم SDK ش بصورت جداگانه قابل نصب هست و کار آدمم خیلی خوب راه میندازه
اینم لینکش
https://developer.nvidia.com/cuda-toolkit-42-archive (https://developer.nvidia.com/cuda-toolkit-42-archive)
نکته دیگه اینه که باید حواستون باشه موقع دانلود cuda toolkit و cuda sdk به 64 یا 32 بیتی بودن ویندوزتون هم توجه کنید.

بعد ویژوال استودیو 2010 یا 2008 یا 2005 رو نصب کنید.

من خودم 2010 رو نصب کردم

حالا برای ایجاد یک پروژه کوچیک کودا مراحل زیر رو برید

1- ویژوال C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎ 2010 رو باز کنید

2- از این مسیر یه پروژه جدید سی++ درست کنید

project: file->new->project, select win32 console application

توی پنجره application setting در قمشت application type گزینه consol application رو انتخاب کنید و از قسمت additional options گزینه empty project رو انتخاب کنید و بعدم دکمه finish رو بزنید

بعد یک فایل جدید برنامه نویسی (نه پروژه) cpp درست می کنیم. برای این کار می شه روی پروژه راست کلیک کرد و (add->new item) رو زد

بعد روی فایل جدیدی که درست کردید و پسوند cpp راده راست کلیک کنید و rename رو بزنید و پسوندشو از .cpp. به cu. تغییر بدید

3- حالا مسیر زیر رو برید

tools->options->text editor->file extension

و پسوند cu. رو در قسمت extension بنویسیسد در قسمت Editor هم گزینه Microsoft Visual C++‎ رو انتخاب کنید و دکمه add سپس دکمه ok رو بزنید

توجه کنید که حتما حتما


4- حالا روی پروژه راست کلیک کنید و از منوی باز شده build costomization رو کلیک کنید از پنجره باز شده cuda رو علامت بزنید و دکمه ok رو بزنید

5- بازم روی پروژه تون راست کلیک کنید و این مسیر رو برید

properties -> configuration properties -> linker -> input

و cudart.lib و cuda.libرو در قسمت addithional می نویسیم و ok می کنیم بازم پنجره رو ok می کنیم ( البته من این دو فایل رو از جایی که کودا رو نصب کردم کپی کردم و بردم ریختم توی پوشه کتابخونه های vc نمی دونم این کار خودسرانه من تاثیری در اجرای برنامه داشته یا همون اضافه کردن کتابخونه ها به لینکر کافیه)
6- یک کار دیگه که یادم رفته بود بنویسم اینه که برنامه تون اجرا بشه باید روی فایل برنامه نویسی که پسوندش رو از cpp به cu تغییر دادین راست کلیک کنید و گزینه properties رو بزنید و در قسمت configuration properties روی قسمت general برید و در فریم کناری از گزینه item type گزینه cuda c/C++‎‎‎‎‎‎‎‎‎‎‎‎‎ انتخاب کنید و ok رو بزنید
با این کار کتابخانه cuda رو هم فعال می کنیم.
یک کار دیگه ای هم که کردم این بود که تمام فایل های هدر این پوشه رو
C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.2\CUDALibraries\common\inc
ریختم توی پوشه
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include
و دیگه هر فایل هدری رو که بخوام راحت می تونم include کنم

یک توصیه من اینه که پروژهتونو ذخیره کنید و یکدور ویژوال استودیو رو ببندید و دوباره باز کنید.

حالا به عنوان مثال می تونید کد زیر رو در فایل cpp تون که به cu تغییر پسوندش دادید بنویسید تا از درایورهاتون گزارش بگیرi
#include<stdio.h>

#include<cuda_runtime.h>
int main(int argc, char** argv)

{
int deviceCount=0;

cudaError_t error_id=cudaGetDeviceCount(&deviceCount);

return 0;

}

من خودم خیلی برای پیدا کردن تمام مراحلی که بالا نوشتم مصیبت کشیدم. توی منابع فارسی که درست و حسابی نیست

لینک منبع انگلیسیش رو هم براتون میگذارم انصافا خدا خیرشون بده که خیلی کمکم کردن توی این لینک می تونید تصاویر راهنمای هر مرحله از کار رو ببینید چون خیلی تصاویر بزرگ بود براتون نگذاشتم

http://www.stevenmarkford.com/installing-nvidia-cuda-with-visual-studio-2010/

هنوز به صروت رسمی شروع به برنامه نویسی با gpu نکردم ایشالا اینبار نتایج و نحوه برنامه نویسی رو که قدم به قدم یاد می گیرم براتون میگذارم
[B]البته اینم بگم که برنامه هاتون رو باید توی مسیری که برنامه های CUDA SDK هست ذخیره کنید وگرنه برنامه اجرا نمی شه(حداقل مال من اجرا نمی شد)
مال من توی این مسیره
C:\DataProgram\NVIDIA GPU Computing Toolkit\CUDA\v4.2\c\src

sibooy
دوشنبه 28 مرداد 1392, 13:18 عصر
یک مثال از CUDA

اگر کد زیر رو در فایل با پسوند cu که درست کردید کپی کنید باید نتایج زمانی رو بهتون نشون بده
برای من بدون خطا اجرا می شه
این برنامه یک آرایه سه بعدی می سازه توی کرنل GPU بهش مفادیر اولیه i*j*k+2 رو میده ور در بدنه اصلی برنامه یعنی همون تابع main بررسی می کنه ببینه آیا مقادیر درست هستن یا نه اگر مقادیر درست بودن برنامه بدون مشکل اجرا می شه وگرنه میگه که در خونه شماره فلان تفاوت مقدار هست. امیدوارم برای شما هم بدون مشکل اجرا شه.
یه همچین مثالی که خیلی برای یاد گرفتن روش نوشتن برنامه به من کمک کرد
فایل .cu برنامه رو ضمیمه پست کردم اگر نتونستید دانلود کنید توی این آدرس هم آپلود کردم
http://sibooy.persiangig.com/examcu.cu
خدا کنه که به درد شما هم بخوره
#include <iostream>

#include <cuda.h>

#include<cuda_runtime.h>

#include <conio.h>

#include<cutil.h>

#include<time.h>

#define DATAXSIZE 10

#define DATAYSIZE 10

#define DATAZSIZE 10

#define N1 10

#define N2 10

#define N3 10

//define the chunk sizes that each threadblock will work on

#define BLKXSIZE 32

#define BLKYSIZE 4

#define BLKZSIZE 4

typedef float MATRIX[DATAYSIZE][DATAXSIZE];



float result=0,result1=0;

int i,j,k;

const dim3 blockSize(BLKXSIZE, BLKYSIZE, BLKZSIZE);

const dim3 gridSize(((DATAXSIZE+BLKXSIZE-1)/BLKXSIZE), ((DATAYSIZE+BLKYSIZE-1)/BLKYSIZE), ((DATAZSIZE+BLKZSIZE-1)/BLKZSIZE));



const int nx = DATAXSIZE;

const int ny = DATAYSIZE;

const int nz = DATAZSIZE;

MATRIX *vv; // storage for result stored on host

MATRIX *d_vv; // storage for result computed on device

// for cuda error checking

#define cudaCheckErrors(msg) \

do { \

cudaError_t __err = cudaGetLastError(); \

if (__err != cudaSuccess) { \

fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \

msg, cudaGetErrorString(__err), \

__FILE__, __LINE__); \

fprintf(stderr, "*** FAILED - ABORTING\n"); getch();\

return 1; \

} \

} while (0)



// device function to set the 3D volume

__global__ void set(float gg[][DATAYSIZE][DATAXSIZE])

{

unsigned idx = blockIdx.x*blockDim.x + threadIdx.x;

unsigned idy = blockIdx.y*blockDim.y + threadIdx.y;

unsigned idz = blockIdx.z*blockDim.z + threadIdx.z;



if ((idx < (DATAXSIZE)) && (idy < (DATAYSIZE)) && (idz < (DATAZSIZE)))

{gg[idz][idy][idx]=idx*idy*idz;}

__syncthreads();

if ((idx < (DATAXSIZE)) && (idy < (DATAYSIZE)) && (idz < (DATAZSIZE)))

{gg[idz][idy][idx]=gg[idz][idy][idx]+2.0;}



}



int main(int argc, char *argv[])

{ clock_t start, end,start1,end1;



// allocate storage for data set

if ((vv = (MATRIX *)malloc((nx*ny*nz)*sizeof(float))) == 0) {fprintf(stderr,"malloc1 Fail \n"); return 1;}



float result,result1;

cudaMalloc((void **) &d_vv, (nx*ny*nz)*sizeof(float));

cudaCheckErrors("Failed to allocate device buffer");

//start= clock();

cudaMemcpy(d_vv, vv, ((nx*ny*nz)*sizeof(float)), cudaMemcpyHostToDevice);

cudaCheckErrors("CUDA memcpy failure");

// compute result

start= clock();

set<<<gridSize,blockSize>>>(d_vv);

end=clock();

cudaCheckErrors("Kernel launch failure");

// copy output data back to host



cudaMemcpy(vv, d_vv, ((nx*ny*nz)*sizeof(float)), cudaMemcpyDeviceToHost);

cudaCheckErrors("CUDA memcpy failure");



//end=clock();

result=((float(end-start))/CLOCKS_PER_SEC);

printf("\n GPU Time= %lg\n",result);



printf("gridsize Device = %d\n", gridSize.x*gridSize.y*gridSize.z);

printf("blockSize Device = %d\n", blockSize.x*blockSize.y*blockSize.z);

// and check for accuracy

start1= clock();

for ( k=0; k<nz; k++)

for ( j=0; j<ny; j++)

for ( i=0; i<nx; i++)

if (vv[k][j][i] != float(i*j*k+2) )

{

printf("Mismatch at x= %d, y= %d, z= %d Host= %d, Device = %lf\n", i, j, k, (i*j*k+2.0), vv[k][j][i]);

getch();

return 1;

}

end1=clock();



printf("CLOCKS_PER_SEC=%d\n",CLOCKS_PER_SEC);

result1=((float(end1-start1))/CLOCKS_PER_SEC);

printf("\n CPU Time= %lg",result1);

free(vv);

cudaFree(d_vv);

cudaCheckErrors("cudaFree fail");

getch();

return 0;

}

sibooy
چهارشنبه 30 مرداد 1392, 13:23 عصر
استفاده از مدل fork-join در OpenMP
من توی این قسمت دو تا قطعه کد براتون گذاشتم.
توی قسمت اول همه دستورات به همراه دستورات حلقه باهم قاطی پاتی اجرا می شن. (اما ما می خوایم حلقه for جدا اجرا بشه)
قطعه کد اول رو ببینید

#pragma omp parallel shared(i,j,a) num_threads(4)

{
k=omp_get_num_procs();
printf("number of processor= %d \n",k);
k=omp_in_parallel();
printf("if program in paralle=1 or serial=0 ?? %d \n",k);
k=omp_get_max_threads();
printf("muaximum number of thread= %d \n",k);
k=omp_get_num_threads();
printf("number of threads= %d \n",k);
k=omp_get_thread_num();
printf("thread number is= %d \n",k);

#pragma omp for
for(j=0;j<10;j++)
printf("%d",j);

}


توی قطعه کد بالا همه چی قاطی چاپ می شه. حالا قطعه کد دوم رو ببینید که از دوتا منطقه موازی استفاده شده

printf("serial region \n");
printf("**************** \n");
printf("parallel region 1 \n");
#pragma omp parallel shared(i,j,a) num_threads(4)

{
k=omp_get_num_procs();
printf("number of processor= %d \n",k);
k=omp_in_parallel();
printf("if program in paralle=1 or serial=0 ?? %d \n",k);
k=omp_get_max_threads();
printf("muaximum number of thread= %d \n",k);
k=omp_get_num_threads();
printf("number of threads= %d \n",k);
k=omp_get_thread_num();
printf("thread number is= %d \n",k);
}
printf("serial region \n");
printf("**************** \n");
printf("parallel region 2 \n");
#pragma omp parallel shared(i,j,a) num_threads(4)
{
#pragma omp for
for(j=0;j<10;j++)
printf("%d",j);

}

در این قطعه کد اول محدوده موازی اول اجرا می شه بعد از اون حلقه موازی اجرا می شه
توضیحات مفصل در مورد مدل fork-join رو در پست زیر ببینید

sibooy
چهارشنبه 30 مرداد 1392, 13:26 عصر
مدل fork-join در OpenMP
رابط OpenMP برای ماشین های حافظه مشترکِ چندپردازنده ای و چندهسته ای طراحی شده که از یک مدل اجرای موازی fork -join استفاده می کند. گرچه مدل fork-join می تواند برای حل مسائل گوناگونی استفاده شود، اما تا حدودی می توان گفت که عملا برای برنامه های کاربردی که اساس آن ها کار روی آرایه ها است مناسب تر است. رابط OpenMP برنامه ها را به دو شکل موازی و ترتیبی اجرا می کند.
اساس کار OpenMP موازی کاری با نخ ها است. یک برنامه نوشته شده با OpenMP C++‎‎‎ API اجرای برنامه را با یک نخ تکی شروع می کند که نخ اصلی نام دارد. نخ اصلی تا زمانی که با اولین ساختار موازی رو به رو گردد بصورت ترتیبی اجرا می شود. در OpenMP C++‎‎‎ API، رهنمود موازی، یک ساختار موازی را تشکیل می دهد. هنگامی که نخ اصلی با یک ساختار موازی برخورد کرد، یک دسته از نخ ها را ایجاد می کند و خود سرپرست آن گروه می شود. هر نخ اجرای بخشی از کار را بصورت پویا در محدوده ی قسمت موازی، به غیر از ساختارهای کار مشترک به عهده می گیرد (OpenMP 2002).
https://computing.llnl.gov/tutorials/openMP/images/fork_join2.gif
انشاءالله در پست های بعد در مورد ساختارهای کارمشترک صحبت می کنم.
دوستان اگه مطلبی بلد هستید دریغ نکنید دیگه.
کسی هست بدونه چطور میشه با MPI برنامه نوشت. اصلا سیستم برنامه نویسیش چطوره؟

sibooy
شنبه 25 آبان 1392, 20:30 عصر
نکته:
OpenMP و CUDA هردو برای معماری shared memory یعنی حافظه اشتراکی ایجاد شدن. با استفاده از OpenMP می شه برای استفاده از چند پردازنده هم برنامه نوشت فقط مخصوص پردازنده های چندهسته ای نیست. فقط باید توجه داشته باشید این چند پردازنده از معماری حافظه اشتراکی باید استفاده کنن نه message passing.

sibooy
سه شنبه 12 آذر 1392, 12:14 عصر
شرح تعدادی از دستورات مهم مثال CUDA ارائه شده در پست شماره 5
سلام
امروز چندتا از دستورات کلیدی cuda رو شرح میدم.
1- برای اینکه بتونید از cuda در برنامه تون استفاده کنید باید چندتا فایل رو include کنید. (اول همه تنظیماتی که در پست های قبل گفتم رو باید انجام داده باشید)
البته برای کارای پیشرفته تر باید فایل های اضافه دیگه ای رو هم include کنید که بستگی به کاری که می خواید انجام بدین داره اما همین اول کاری که ما فقط داریم روی آرایه ها کار می کنیم include این دوتا فایل برای استفاده از cuda کافیه

#include <cuda.h>

#include<cuda_runtime.h>

برای مثال ما می خوایم برنامه ای رو که در پست های قبل گذاشتم رو ببینیم هر کدوم از دستوراتش به چه کاری میان
شما میخواید روی یک آرایه سه بعدی کار کنید و ببینید محاسباتتون در cpu سریعتر انجام می شه یا در GPU (همون پردازنده گرافیکی تون)
اول باید مشخص کنید که هر کدوم از ابعاد آرایه تون چه اندازه ای داره؟ مثلا یک آرایه 10*10*10.
آرایه تون رو باید بصورت اشاره گر تعریف کنید نه به صورت استاتیک(درحالت معمول). بصورت زیر تعریف کنید:
اول مشخص کنید چه عددی رو برای هر بعد درنظر گرفتید

#define DATAXSIZE 10

#define DATAYSIZE 10

#define DATAZSIZE 10

حالا من برای راحتی کارم یه نوع داده ای جدید به اسم matrix ایجاد کردم که به وسیله اون می تونم به راحتی هرچندتا آرایه که خواستم تعریف کنم.

typedef float MATRIX[DATAYSIZE][DATAXSIZE];

این matrix ما فعلا فقط ابعاد x و y ش مشخصه. (چون داریم از اشاره گر ها استفاده می کنیم بعد z رو بعدا مشخص می کنیم حالا بعدا میگم چطوری)
یه اشاره گر به ماتریس ایجاد می کنیم بر روی RAM که CPU مون باهاش کار می کنه (از نوع داده ای جدید به اسم matrix)

MATRIX *vv; // storage for result stored on host

یه اشاره گر ماتریس دیگه ایجاد می کنیم که روی حافظه پردازنده گرافیکی هست و GPU مون باهاش کار می کنه. اونم از نوع matrix هست. (البته بگ اینجا مشخص نمی شه که شما هر کدوم از این ماتریس ها رو برای کدوم حافظه استفاده می کنید. بعدا براتون میگم از کجا مشخص کنید.

MATRIX *d_vv; // storage for result computed on device

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

#define BLKXSIZE 32

#define BLKYSIZE 4

#define BLKZSIZE 4

این قسمت مشخص میکنه که بلوک شما سه بعدی هست و ابعادش چقدره

const dim3 blockSize(BLKXSIZE, BLKYSIZE, BLKZSIZE);

در قسمت بعد مشخص می کنه با توجه به اندازه آرایه تون gridی که رو پردازنده گرافیکی نخ های شما رو مدیریت می کنه به چه اندازه باید باشه و از چندتا بلوک نخ تشکیل شده

const dim3 gridSize(((DATAXSIZE+BLKXSIZE-1)/BLKXSIZE), ((DATAYSIZE+BLKYSIZE-1)/BLKYSIZE), ((DATAZSIZE+BLKZSIZE-1)/BLKZSIZE));

حالا این قسمت های سبز رو بپذیرید تا در یک پست جداگانه مفصل تر توضیح بدم که چرا این ابعاد رو استفاده کردیم و حکمتش چیه.

خب حالا بریم توی بدنه اصلی برنامه main()
اول از همه تعریف آرایه مون رو در RAM کامپیوتر تکمیل می کنیم. این قسمت مشخص می کنه که یه ماتریس vv رو که قبلا از نوع matrix تعریف کردیم دقیقا چه ابعادی داره. دستور malloc مقدار nx*ny*nz خونه از حافظه رو به اندازه نوع داده ای float به ماتریس vv میده. دستور if هم مشخص می کنه که اگر این تخصیص درست انجام نشد (یعنی تابع malloc مقدار 0 برگردوند) پیغام بده که خطا اتفاق افتاده.

// allocate storage for data set

if ((vv = (MATRIX *)malloc((nx*ny*nz)*sizeof(float))) == 0) {fprintf(stderr,"malloc1 Fail \n"); return 1;}

در این قسمت مشخص می کنیم که d_vv مربوط به حافظه پردازنده گرافیکی هست و اندهزه ش برابر nx*ny*nz هست و هر خونه هم اندازه ش به اندازه متغیر float هست.

cudaMalloc((void **) &d_vv, (nx*ny*nz)*sizeof(float));

اگر در تخصیص فضا به ماتریس در پردازنده گرافیکی به مشکلی برخورد با استفاده از این دستور رشته ای رو که قبل از تعریف تابع main() تعریف کردین نشون میده
و این مقدار رشته ای رو داخل رشته تعریف شده میریزه

cudaCheckErrors("Failed to allocate device buffer");

اگر در تخصیص فضا مشکلی نبود میاد محتوای ماتریس vv رو که داخل RAM قرار داره درون ماتریس d_vv که درون حافظه پردازنده گرافیکی قرار داره کپی می کنه(مخصوصا برای وقتایی که مقدار اولیه تون خارج از کرنل تولید میشه لازمه. به هرحال باید این دو فضا رو بهم ربط بدین چون در آخر مقادیر تولید شده توسط GPU باید به حافظه رم منتقل بشه.

cudaMemcpy(d_vv, vv, ((nx*ny*nz)*sizeof(float)), cudaMemcpyHostToDevice);

حالا این دستور مشخص می کنه که آیا در این عملیات کپی خطایی صورت گرفته یا خیر

cudaCheckErrors("CUDA memcpy failure");

حالا از این به بعد باید وارد کرنل GPU مون بشیم و بگیم که محاسبات از این به بعد درون GPU انجام بشه . این دستور یه کرنل ایجاد می کنه به نام set که مشخص می کنه از چندتا بلوک نخ استفاده شده(توسط gridSize) و هر بلوک نخ چندتا نخ می تونه داشته باشه(blockSize) و در قسمت پرانتز هم d_vv به کرنل فراخوانی می شه.

set<<<gridSize,blockSize>>>(d_vv);

این دستور مشخص میکنه که اگر در اجرای کرنل مشکلی ایجاد شد پیام خطا میده

cudaCheckErrors("Kernel launch failure");

خب بعد از اینکه محاسبات در هسته GPU اجرا شد لازمه که این نتیجه محاسبات دوباره به ماتریس داخل RAM کپی بشه.

cudaMemcpy(vv, d_vv, ((nx*ny*nz)*sizeof(float)), cudaMemcpyDeviceToHost);

حالا اگر خطایی در این عمل کپی کردن وجود داشته باشه دستور زیر اونو به ما اطلاع میده

cudaCheckErrors("CUDA memcpy failure");


کار با GPU تموم شد و بقیه دستورا مربوط به CPU هست.
نکته مهمی که وجود داره اینه که بخش زمان بر کار مربوط به کپی داده ها از RAM به حافظه GPU و برعکس هستش.
اجرای هسته GPU هم معمولا کمتر از یک میلی ثانیه زمان می بره. من که هرچه زمان اجرای هسته رو اندازه گرفتم نتیجه صفر میلی ثانیه بوده(لابد در حد هزارم ثانیه)
اما عملیات کپی داده ها از RAM به حافظه GPU و برعکس متناسب با قدرت GPU و پهنای باندش ممکنه چند ده ثانیه زمان بگیره (شایدم بیش از صد ثانیه) که این زمان کاملا به حجم ماتریس شما بستگی داره.
اگر زمان انجام محاسبات شما روی CPU مثلا ده هزار ثانیه زمان می بره خیلی معقوله شما صد ثانیه برای کپی داده ها به GPU و برعکس مصرف کنید اما محاسباتتون کمتر از یک میلی ثانیه اجرا بشه. اون وقت می تونید با خوشحالی بگید کل زمان اجرا مثلا 100 ثانیه بوده ( نه کمتر از یک میلی ثانیه:شیطان:)
اما اگر زمان محاسبات شما 5 ثانیه هست اون وقت این عملیات کپی شاید نیم ثانیه طول بکشه.
اون وقت نمی ارزه که شما یک میلیون و نیم بابت خرید یه کارت گرافیک قابل برنامه نویسی خوب هزینه کنید:شیطان::شیطان::شیطان::شی ان::شیطان:
توضیح دستورای داخل هسته GPU که تابعش قبل از تابع main() نوشته شده بماند برای بعد
امیدوارم مفید بوده باشه.
اگر شما هم توضیحی در این مورد دارید بفرمایید ما هم استفاده کنیم

ali chegini
سه شنبه 12 آذر 1392, 13:56 عصر
سلام.منم برای درس شیوه ارائه پردازش موازی با GPU رو ارائه داده بودم.یادش بخیر. حالا پی دی افش رو میزارم. انشالله مفید باشه.

ar.1171373
جمعه 15 آذر 1392, 10:18 صبح
سلام دوست عزیز... خیلی ممنون بابت آموزش... واقعا نیاز داشتم و بسیار سر در گم بودم
من یه برنامه ای داشتم که میخواستم کاری کنم از همه هشت تا هسته استفاده کنه و کارایی ۱۰۰٪ بشه...
این کار ها را کردم ک گفتید و مقالات را هم خوندم
برنامه به صورت موازی اجرا میشه پلی متاسفانه همه section ها توی همون یدونه هسته اجزا میشن
و این اتفاق نمیفته ک هر section را اختصاص بده به یک هسته و از همه هسته ها استفاده کنه...
لطفا لطفا کمکم کن....مرسی

asdasd123123
دوشنبه 18 آذر 1392, 10:02 صبح
دوستان من اینترنت رو گشتم و به این نتیجه رسیدم که openCL بهتره چون:
- نسبت به boost و openmp گسترده تره و علاوه بر پردازش موازی از استفاده ی gpu کنار cpu هم بهره می بره
- نسبت به cuda بهتره چون اون رو فقط nvidia ساپرت می کنه ولی openCL رو AMD ، IBM ، Nvidia ، Apple ، Intel و ... ساپرت می کنن
- در ضمن می تونید از openCL در کنار openGL استفاده کنید

نظر شما چیه؟

sibooy
دوشنبه 18 آذر 1392, 12:43 عصر
دوستان من اینترنت رو گشتم و به این نتیجه رسیدم که openCL بهتره چون:
- نسبت به boost و openmp گسترده تره و علاوه بر پردازش موازی از استفاده ی gpu کنار cpu هم بهره می بره
- نسبت به cuda بهتره چون اون رو فقط nvidia ساپرت می کنه ولی openCL رو AMD ، IBM ، Nvidia ، Apple ، Intel و ... ساپرت می کنن
- در ضمن می تونید از openCL در کنار openGL استفاده کنید

نظر شما چیه؟

سلام
من درمورد opencl اطلاعی ندارم و تحقیق هم نکردم. فقط توی زمینه کاری که انجام دادم دیدم اکثر قریب به اتفاق ستاره شناسایی که برای کارای محاسباتی شون از پردازنده گرافیکی استفاده کردن با استفاده از CUDA بوده.
حالا اگر شما اطلاعاتی از oenCL دارید بذارید ما و بقیه دوستان استفاده کنیم مخصوصا اگر درمورد چگونگی برنامه نویسی با اون اطلاعاتی دارین قدم به قدم بذارید تا نحوه برنامه نویسی و کار کردن با openCL رو هم یاد بگیریم. خدا یک در دنیا صد در آخرت عوض خیر بهتون بده

sibooy
سه شنبه 26 آذر 1392, 16:26 عصر
توابع محیط اجرایی در OpenMP
یه چندتا تابع هست که برای تاثیر گذاشتن و نظارت بر نخ های پردازشی در محیط موازی به کار می ره.

* the omp_set_num_threads function.
* the omp_get_num_threads function.
* the omp_get_max_threads function.
* the omp_get_thread_num function.
* the omp_get_num_procs function.
* the omp_in_parallel function.
* the omp_set_dynamic function.
* the omp_get_dynamic function.
* the omp_set_nested function.
* the omp_get_nested function.

هر کدام از این تابع ها یک سری کار رو برای ما انجام میدن.
چندتاش رو الان توضیح میدم باقیش رو ایشالا اگه عمری بود بعدا خواهم گفت
اولین تابع omp_set_num_thread هست. این تابع یک تعداد پیش فرض برای تعداد نخ های منطقه موازی تعیین می کنه. اگر شما در تعریف قسمت موازی مشخص نکرده باشید که تعداد نخ ها چندتا باشه این دستور مشخص می کنه که تعداد thread ها چندتا هست.

omp_set_num_threads(int num_threads);

مقدار num_thread باید یه عدد صحیح مثبت باشه.
این تابع رو حتما باید قبل از ورود به محوطه موازی بنویسید. یعنی قبل از دستور

#pragma omp parallel

درضمن وقتی وارد محیط موازی سازی میشید می تونید با num_thread() تعدا نخ هایی رو که این منطقه موازی رو اجرا می کنن مشخص کنید.
یعنی اینطوری

#pragma omp parallel num_threads(4)

همه این گفته ها یعنی اینکه اگر دستورات شما به این صورت بود

omp_set_num_threads(6);
#pragma omp parallel num_threads(4)

اول تعداد threadهای شما 6 تا تعیین می شه ولی وقتی به دستور دوم رسید چون اولیوت num_thread(4) بیشتره تعداد نخ های شما برای محیط موازی 4 تا تعیین می شه.
حالا اگر شما برای محیط موازی تون num_thread رو استفاده نکرده باشید تعداد threadهای شما 6 خواهد بود


تابع دوم omp_get_num_threads هست. این تابع در محیط موازی تعداد نخ هایی که محیط موازی شما رو اجرا می کنن بهتون برمی گردونه که یک عدد صحیح هست.
یک متغیر از نوع int تعریف کنید و برای دستور به کار ببرید.

int a;
a=omp_get_num_threads();
printf("%d", a);


اگر میخواید بدونید شماره نخی که قسمتی از برنامه رو داره اجرا می کنه چنده از تابع


omp_get_thread_num();


استفاده کنید. این تابع هم یک مقدار صحیح رو به عنوان شماره نخ به شما برمی گردونه
که البته مقدار رو داخل یک متغیر صحیح که شما براش تعریف کردید میریزه.


int k;
k=omp_get_thread_num();
printf("thread number is= %d \n",k);



من خودم یه مشکلی که داشتم این بود که تنظیماتی رو که باید روی VC++‎ 2010 انجام می دادم تا OpenMP رو صحیح اجرا کنه بلد نبودم. برای همین محیط موازی بصورت ترتیبی اجرا می شد.

خب حالا برای اینکه بفهمید که محیط موازی تون داره موازی اجرا می شه یا بصورت سریال از تابع

omp_in_parallel();

باید استفاده کنید.
اگر این تابع مقدار صفر رو برگردوند که یعنی محیطتون موازی اجرا نمی شه.(وارد محیط موازی سازی نشدین)
وگرنه مقدار غیر از صفر یعنی اینکه محیطتون داره موازی اجرا می شه (به گمانم 1 رو بر می گردونه درست یادم نمونده)
این تابع هم عدد اینتیجر بر می گردونه.

k=omp_in_parallel();
printf("if program in paralle=1 or serial=0 ?? %d \n",k);


خب طولانی شد اگر عمری بود بقیه توابع رو براتون توضیح میدم.
شما هم بیکار نباشید اگر بقیه توابع رو بلدید منظر من نمونین و خودتون باقی توابع رو توضیح بدین تا خلق خدا استفاده کنن.
موفق باشید
دعا یادتون نره.:لبخندساده:

gegheleh2004
جمعه 13 دی 1392, 21:59 عصر
با سلام ازتون واقعا متشکرم تمام مراحل رو دقیق رفتم ولی بازم این یغام ها رو میده



و برای برنامه ای که در این لینک گداشته اید
و من در این آدرس ذخیر ه اش کردم C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\src
این خطاها رو میده(توی مسیر آدرس من C نداره)

میشه اگه ممکنه بازم کمکم کنید و بگید این pdb file چیه و از کجا باید کجا بذارمش (من برای پایان نامه ارشدم حداکثر یک ماه دیگه فرصت دارم ممنون میشم اگه ممکنه راهی سریعتر برای تماس باهاتون بهم معرفی کنید)
باتشکر فراوان


'e1.exe': Loaded 'C:\Users\Part\Documents\Visual Studio 2010\Projects\e1\Debug\e1.exe', Symbols loaded.

'e1.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\bin\cudart32_42_9.dll', Binary was not built with debug information.

'e1.exe': Loaded 'C:\Windows\SysWOW64\msvcr100d.dll', Symbols loaded.

'e1.exe': Loaded 'C:\Windows\SysWOW64\nvcuda.dll', Binary was not built with debug information.

'e1.exe': Loaded 'C:\Windows\SysWOW64\user32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\gdi32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\lpk.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\usp10.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\msvcrt.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\advapi32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\sechost.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\rpcrt4.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\sspicli.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\cryptbase.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\setupapi.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\cfgmgr32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\oleaut32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\ole32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\devobj.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\shell32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\shlwapi.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\ws2_32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\nsi.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\imm32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\msctf.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\nvinit.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Program Files (x86)\NVIDIA Corporation\coprocmanager\detoured.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Program Files (x86)\NVIDIA Corporation\coprocmanager\Nvd3d9wrap.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Program Files (x86)\NVIDIA Corporation\coprocmanager\nvdxgiwrap.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\dwmapi.dll', Cannot find or open the PDB file

'e1.exe': Unloaded 'C:\Windows\SysWOW64\dwmapi.dll'

'e1.exe': Loaded 'C:\Windows\SysWOW64\nvapi.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\version.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\wintrust.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\crypt32.dll', Cannot find or open the PDB file

'e1.exe': Loaded 'C:\Windows\SysWOW64\msasn1.dll', Cannot find or open the PDB file

The program '[5728] e1.exe: Native' has exited with code 0 (0x0).

(gegheleh2004@yahoo.com)

sibooy
چهارشنبه 18 دی 1392, 09:23 صبح
سلام
می بخشید اصل مسیر ذخیره فایل
c:\data program درسته نه آدرس c:\program files
توی پست ها اشتباه نوشته بودم که درستش کردم
حتما خبرم کنید

sibooy
چهارشنبه 18 تیر 1393, 18:49 عصر
یک برنامه برای اینکه تفاوت زمان اجرا رو در حالت سریال و موازی نشون بده. همچنین تفاوت زمان اجرا با تعداد thread های مختلف
خب برای کاربرای OpenMP من یک نمونه کد رو میگذارم شما اجرا کنید و نتیجه رو ببینید

#include<stdlib.h>
#include<time.h>
#include<omp.h>
#include<iostream>
#include<conio.h>
#define Nz 100
#define Nx 100
#define Ny 100

int main(int argc, char* argv[])
{clock_t start, end,start1,end1,start2, end2, start3,end3;
if ((a = (MATRIX *)malloc((Nx*Ny*Nz)*sizeof(float))) == 0) {fprintf(stderr,"malloc1 Fail \n"); return 1;}
if ((b = (MATRIX *)malloc((Nx*Ny*Nz)*sizeof(float))) == 0) {fprintf(stderr,"malloc1 Fail \n"); return 1;}
if ((c = (MATRIX *)malloc((Nx*Ny*Nz)*sizeof(float))) == 0) {fprintf(stderr,"malloc1 Fail \n"); return 1;}
int numtd, k , i , j;
numtd=4;
printf("please enter number of thread: ");
scanf("%d",& numtd);
// *************initial value************
for (k=0;k<Nz;k++)
for (j=0;j<Ny;j++)
for (i=0;i<Nx;i++)
{
a[k][j][i]=i*j*k;
b[k][j][i]=i+k+j;
}
//######################
#pragma omp parallel num_threads(numtd) private(j)

{
k=omp_get_num_procs();
printf("number of processor= %d \n",k);
k=omp_in_parallel();
printf("if program in paralle=1 or serial=0 ?? %d \n",k);
k=omp_get_max_threads();
printf("muaximum number of thread= %d \n",k);
k=omp_get_num_threads();
printf("number of threads= %d \n",k);
}


//######################

// *****************main value*************
start=clock();
#pragma omp parallel num_threads(numtd) private(i,j,k)

{
#pragma omp for ordered schedule (static)
for (k=0;k<Nz;k++)
for (j=0;j<Ny;j++)
for (i=0;i<Nx;i++)
c[k][j][i]=a[k][j][i]+b[k][j][i];

}
end=clock();
double result;


result=((double(end-start))/CLOCKS_PER_SEC);
printf("\n parallel with %d thread Time= %lg\n",numtd,result);
getch();
return 0;
}


اگر برنامه شما وارد محیط موازی بشه تعداد thread ها رو که تغییر بدین زمان اجرای حلقه هم متفاوت خواهد بود. برای من که بهترین زمان اجرا مال وقتیه که تعداد thread ها رو به تعداد هسته های CPU میگیرم.
اگر تعداد thread ها رو 1 وارد کنید برنامه تون بصورت سریال اجرا می شه. اگر 2 و بیشتر وارد کنید برنامه بصورت موازی اجرا خواهد شد (بشرطی که تنظیمات رو درست انجام داده ابشید)

hadidan
پنج شنبه 04 دی 1393, 12:46 عصر
با سلام به دوستان
برای اطلاع بیشتر این لینک مفید هستش
http://hpclab.ir/index.php/84-parallel/119-mpi

robabehsh
دوشنبه 12 بهمن 1394, 00:15 صبح
با سلام خدمت دوستان
من مدت کوتاهیه دارم با کودا کار میکنم. میخواستم بپرسم میشه با نوع داده ی string تو کودا کار کرد؟ من یه آرایه ی بزرگ از رشته ها دارم که میخوام با کودا مرتبشون کنم. یعنی در واقع میخوام با کودا به صورت موازی این آرایه رو مرتب کنم. اما نوع داده ی string رو نمیشناسه. کسی میتونه لطفاً یه مثال خوب تو این زمینه بذاره؟
ممنون میپشم کمکم کنید.

دانشجوmf
سه شنبه 13 آذر 1397, 16:02 عصر
سلام من این کد به C++‎‎‎‎‎‎ رو دارم و می خوام با openmp موازی اش کنم (کد مرتب سازی درختی هست) ولی متاسفانه طبق قانون موازی سازی بعد از اجرای موازی کاملا اعداد به هم ریخته نشون میده میشه راهنمایی کنید

#include "pch.h"
#include <iostream>
#include<string.h>
#include<new>
#include<omp.h>
#include<stdC++‎‎‎‎‎‎.h>

using namespace std;
struct Node
{
int key;
struct Node *left, *right;
};

struct Node *left, *right;
struct Node *newNode(int item)
{
struct Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;

}
void storesorted(Node *root, int arr[], int &i)
{
if (root != NULL)
{
storesorted(root->left, arr, i);
arr[i++] = root->key;
storesorted(root->right, arr, i);
}
}
Node* insert(Node* node, int key)
{
if (node == NULL)return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
return node;

}
void treeSort(int arr[], int n)
{
struct Node *root = NULL;
root = insert(root, arr[0]);
for (int i = 1; i < n; i++)
insert(root, arr[i]);
int i = 0;
storesorted(root, arr, i);

}

int main()
{



//create input array
int arr[] = { 5, 4, 7, 2, 11 };
int n = sizeof(arr) / sizeof(arr[0]);

treeSort(arr, n);

#pragma omp parallel
{

int n = omp_get_num_threads();

for (int i = 0; i < n; i++)
cout << arr[i] << " ";

}

return 0;








}




این نمایش کامپیوتر قبل از موازی سازی هستش
149368



و این هم بعد از نوشتن همون خط openmp
149367

farhad_shiri_ex
چهارشنبه 14 آذر 1397, 09:06 صبح
سلام من این کد به C++‎‎‎‎‎‎‎‎‎‎‎ رو دارم و می خوام با openmp موازی اش کنم (کد مرتب سازی درختی هست) ولی متاسفانه طبق قانون موازی سازی بعد از اجرای موازی کاملا اعداد به هم ریخته نشون میده میشه راهنمایی کنید

#include "pch.h"
#include <iostream>
#include<string.h>
#include<new>
#include<omp.h>
#include<stdC++‎‎‎‎‎‎‎‎‎‎‎.h>

using namespace std;
struct Node
{
int key;
struct Node *left, *right;
};

struct Node *left, *right;
struct Node *newNode(int item)
{
struct Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;

}
void storesorted(Node *root, int arr[], int &i)
{
if (root != NULL)
{
storesorted(root->left, arr, i);
arr[i++] = root->key;
storesorted(root->right, arr, i);
}
}
Node* insert(Node* node, int key)
{
if (node == NULL)return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
return node;

}
void treeSort(int arr[], int n)
{
struct Node *root = NULL;
root = insert(root, arr[0]);
for (int i = 1; i < n; i++)
insert(root, arr[i]);
int i = 0;
storesorted(root, arr, i);

}

int main()
{



//create input array
int arr[] = { 5, 4, 7, 2, 11 };
int n = sizeof(arr) / sizeof(arr[0]);

treeSort(arr, n);

#pragma omp parallel
{

int n = omp_get_num_threads();

for (int i = 0; i < n; i++)
cout << arr[i] << " ";

}

return 0;








}




این نمایش کامپیوتر قبل از موازی سازی هستش
149368



و این هم بعد از نوشتن همون خط openmp
149367

خوب این که طبیعی شما تعداد نخ های فعال تو ناحیه موازی سازی را به عنوان رفرنس تکرار حلقه استفاده کردید




int n = omp_get_num_threads();


این یعنی به تعداد تمام نخ هایی که ناحیه موازی سازی ایجاد کرده حلقه شما اجرا میشه و هرکدوم از نخ ها دارند حلقه خودشون را اجرا میکنن که همین باعث تکراری شدن مقادیر آرایه میشه! کلا مبحث موازی سازی را اشتباه برداشت کردید.
زمانی هم که از ناحیه موازی سازی استفاده نمیکنید هم که کاملا مشخص که باید درست باشه چون توی یک نخ هست و تعداد تکرار حلقه هم براساس تعداد آرایه ها می باشد.
تکنیک های موازی سازی که نکات data collision , race condition و... را رعایت نکرده باشند نه تنها موازی سازی معنی نداره بلکه باعث تولید خروجی های اشتباه هم می شود.