نمایش نتایج 1 تا 21 از 21

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

  1. #1

    Lightbulb برنامه نویسی موازی در C++‎‎‎‎‎ با پردازنده های چندهسته ای، پردازنده های گرافیکی وچند پردازنده ای

    دوستان سلام
    در این تاپیک می خوام از همه دعوت کنم که اگر مطلبی درمورد برنامه نویسی موازی در C یا C++‎‎‎‎‎‎‎‎‎‎‎ بلدین اینجا بذارین.
    من خودم با CUDA و OpenMP کار کردم. هرچه رو هم یاد گرفتم اینجا میذارم. شما هم هرچه می دنید دریغ نکنید

    اول OepenMP:
    یک کتابخانه ست که به C و C++‎‎‎‎‎‎‎‎‎‎‎ اضافه می شه و می تونید با اون برنامه هاتون رو موازی کنید بطوریکه اگر چندتا پردازنده و یا یه پردازنده چند هسته ای داشته باشید همه پردازنده ها رو برای پردازش بکار بگیره.
    نحوه راه اندازیش رو Visual Studio 2010 توی این تاپیک در پست های پایین و همچنین توی این لینک گذاشتم


    دوم CUDA:
    یک گسترش کوچیک از C هست که بازم بصورت کتابخانه به C++‎‎‎‎‎‎‎‎‎‎‎ اضافه می شه. برای استفاده از اون باید از محیط visual studio 2005 یا 2008 یا 2010 استفاده کنید. از CUDA برای اجرای برنامه روی پردازنده گرافیکی استفاده می شه. یعنی شما می تونید محاسباتتون رو بجای CPU روی پردازنده گرافیکی تون اجرا کنید.

    نحوه راه اندازیش روی visual studio C++‎‎‎‎‎‎‎‎‎‎‎2010 رو در پست های پایین گذاشتم همچمین توی این لینکم هست.

    یه برنامه کاربرردی کوچک هم نوشتم که از این لینک می تونید ببینید البته توی پست های پایین همین تاپیک هم گذاشتم.

    شما هم هرچه از برنامه نویسی موازی بلدید بگید که ما و بقیه دوستان استفاده کنیم.
    parallel programming


    ----------------------------------------------
    زکات علم نشر آن است. علی(ع)
    آخرین ویرایش به وسیله sibooy : سه شنبه 28 مرداد 1393 در 22:12 عصر

  2. #2

    نقل قول: برنامه نویسی موازی در C++‎‎ با پردازنده های چندهسته ای، پردازنده های گرافیک و چندپردازنده ای

    برنامه نویسی موازی با 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 رو خیلی خوب با مثال توضیح میده. به علت رعایت قانون کپی رایت متن مطلب رو اینجا نمی نویسم اما لینکش رو میگذارم(درست برو بچه های ماهنامه شبکه درد نکنه)

    اینم لینک یه راهنمای خارجی که باز هم دستورات رو خیلی خوب و همراه مثال توضیح داده

    اینم یه نمونه کد کوتاه برای اینکه ببنید برنامه بصورت موازی اجرا می شه یا نه.
    خروجی برنامه باید چاپ اعداد یک تا ده بصورت نامرتب باشه (چون هر عدد توسط یک 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;
    }

    خدا خیر بده هرکسی این داکیومنتو درست کرده (از لینک زیر دانلود کیند)

    اگر میخواید برنامه نویسی بسیار موازی با cuda رو هم تازه شروع کنید این دو لینک خیلی به دردتون خواهد خورد
    برای نصب و راه اندازی cuda روی ویژوال استودیو C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎ به لینک زیر برید

    و برای آشنایی با نحوه نوشتن یک برنامه موازی کوتاه در cuda به لینک زیر برید

    درپناه حق تعالی باشید

    ----------------------------------------------
    زکات علم نشر آن است. علی(ع)
    آخرین ویرایش به وسیله sibooy : سه شنبه 28 مرداد 1393 در 22:15 عصر

  3. #3

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    موازی سازی حلقه های تو در تو در 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 مرداد 1393 در 22:16 عصر

  4. #4

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    آموزش مراحل نصب و راه اندازی 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

    نکته دیگه اینه که باید حواستون باشه موقع دانلود 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/instal...l-studio-2010/

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

  5. #5

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    یک مثال از CUDA

    اگر کد زیر رو در فایل با پسوند cu که درست کردید کپی کنید باید نتایج زمانی رو بهتون نشون بده
    برای من بدون خطا اجرا می شه
    این برنامه یک آرایه سه بعدی می سازه توی کرنل GPU بهش مفادیر اولیه i*j*k+2 رو میده ور در بدنه اصلی برنامه یعنی همون تابع main بررسی می کنه ببینه آیا مقادیر درست هستن یا نه اگر مقادیر درست بودن برنامه بدون مشکل اجرا می شه وگرنه میگه که در خونه شماره فلان تفاوت مقدار هست. امیدوارم برای شما هم بدون مشکل اجرا شه.
    یه همچین مثالی که خیلی برای یاد گرفتن روش نوشتن برنامه به من کمک کرد
    فایل .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;

    }


  6. #6

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    استفاده از مدل 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 رو در پست زیر ببینید

  7. #7

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    مدل fork-join در OpenMP
    رابط OpenMP برای ماشین های حافظه مشترکِ چندپردازنده ای و چندهسته ای طراحی شده که از یک مدل اجرای موازی fork -join استفاده می کند. گرچه مدل fork-join می تواند برای حل مسائل گوناگونی استفاده شود، اما تا حدودی می توان گفت که عملا برای برنامه های کاربردی که اساس آن ها کار روی آرایه ها است مناسب تر است. رابط OpenMP برنامه ها را به دو شکل موازی و ترتیبی اجرا می کند.
    اساس کار OpenMP موازی کاری با نخ ها است. یک برنامه نوشته شده با OpenMP C++‎‎‎‎ API اجرای برنامه را با یک نخ تکی شروع می کند که نخ اصلی نام دارد. نخ اصلی تا زمانی که با اولین ساختار موازی رو به رو گردد بصورت ترتیبی اجرا می شود. در OpenMP C++‎‎‎‎ API، رهنمود موازی، یک ساختار موازی را تشکیل می دهد. هنگامی که نخ اصلی با یک ساختار موازی برخورد کرد، یک دسته از نخ ها را ایجاد می کند و خود سرپرست آن گروه می شود. هر نخ اجرای بخشی از کار را بصورت پویا در محدوده ی قسمت موازی، به غیر از ساختارهای کار مشترک به عهده می گیرد (OpenMP 2002).

    انشاءالله در پست های بعد در مورد ساختارهای کارمشترک صحبت می کنم.
    دوستان اگه مطلبی بلد هستید دریغ نکنید دیگه.
    کسی هست بدونه چطور میشه با MPI برنامه نوشت. اصلا سیستم برنامه نویسیش چطوره؟

  8. #8

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

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

  9. #9

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    شرح تعدادی از دستورات مهم مثال 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() نوشته شده بماند برای بعد
    امیدوارم مفید بوده باشه.
    اگر شما هم توضیحی در این مورد دارید بفرمایید ما هم استفاده کنیم

  10. #10
    کاربر تازه وارد
    تاریخ عضویت
    آبان 1388
    محل زندگی
    NULL
    پست
    87

    نقل قول: برنامه نویسی موازی در C++‎‎‎ با پردازنده های چند هسته ای، پردازنده های گرافیک

    سلام.منم برای درس شیوه ارائه پردازش موازی با GPU رو ارائه داده بودم.یادش بخیر. حالا پی دی افش رو میزارم. انشالله مفید باشه.
    فایل های ضمیمه فایل های ضمیمه

  11. #11

    نقل قول: برنامه نویسی موازی در C++‎‎ با پردازنده های چندهسته ای، پردازنده های گرافیک و چندپردازنده ای

    سلام دوست عزیز... خیلی ممنون بابت آموزش... واقعا نیاز داشتم و بسیار سر در گم بودم
    من یه برنامه ای داشتم که میخواستم کاری کنم از همه هشت تا هسته استفاده کنه و کارایی ۱۰۰٪ بشه...
    این کار ها را کردم ک گفتید و مقالات را هم خوندم
    برنامه به صورت موازی اجرا میشه پلی متاسفانه همه section ها توی همون یدونه هسته اجزا میشن
    و این اتفاق نمیفته ک هر section را اختصاص بده به یک هسته و از همه هسته ها استفاده کنه...
    لطفا لطفا کمکم کن....مرسی

  12. #12
    منتظر تایید آدرس ایمیل
    تاریخ عضویت
    مهر 1392
    محل زندگی
    تهران
    پست
    129

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

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

    نظر شما چیه؟

  13. #13

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

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

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

  14. #14

    Smile برنامه نویسی موازی در C++‎‎‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ای

    توابع محیط اجرایی در 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);


    خب طولانی شد اگر عمری بود بقیه توابع رو براتون توضیح میدم.
    شما هم بیکار نباشید اگر بقیه توابع رو بلدید منظر من نمونین و خودتون باقی توابع رو توضیح بدین تا خلق خدا استفاده کنن.
    موفق باشید
    دعا یادتون نره.
    آخرین ویرایش به وسیله sibooy : سه شنبه 26 آذر 1392 در 20:29 عصر

  15. #15

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

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



    و برای برنامه ای که در این لینک گداشته اید
    و من در این آدرس ذخیر ه اش کردم 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)



  16. #16

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    سلام
    می بخشید اصل مسیر ذخیره فایل
    c:\data program درسته نه آدرس c:\program files
    توی پست ها اشتباه نوشته بودم که درستش کردم
    حتما خبرم کنید

  17. #17

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    یک برنامه برای اینکه تفاوت زمان اجرا رو در حالت سریال و موازی نشون بده. همچنین تفاوت زمان اجرا با تعداد 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 و بیشتر وارد کنید برنامه بصورت موازی اجرا خواهد شد (بشرطی که تنظیمات رو درست انجام داده ابشید)
    آخرین ویرایش به وسیله sibooy : چهارشنبه 18 تیر 1393 در 19:13 عصر

  18. #18
    کاربر تازه وارد آواتار hadidan
    تاریخ عضویت
    فروردین 1389
    محل زندگی
    یکی از روستاهای گیلان
    پست
    73

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    با سلام به دوستان
    برای اطلاع بیشتر این لینک مفید هستش
    http://hpclab.ir/index.php/84-parallel/119-mpi

  19. #19

    نقل قول: برنامه نویسی موازی در C++‎ با پردازنده های چند هسته ای، پردازنده های گرافیک و چند پردازنده ا

    با سلام خدمت دوستان
    من مدت کوتاهیه دارم با کودا کار میکنم. میخواستم بپرسم میشه با نوع داده ی string تو کودا کار کرد؟ من یه آرایه ی بزرگ از رشته ها دارم که میخوام با کودا مرتبشون کنم. یعنی در واقع میخوام با کودا به صورت موازی این آرایه رو مرتب کنم. اما نوع داده ی string رو نمیشناسه. کسی میتونه لطفاً یه مثال خوب تو این زمینه بذاره؟
    ممنون میپشم کمکم کنید.

  20. #20

    نقل قول: برنامه نویسی موازی در C++‎‎‎

    سلام من این کد به 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;








    }



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




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

  21. #21

    نقل قول: برنامه نویسی موازی در C++‎‎‎‎

    نقل قول نوشته شده توسط دانشجوmf مشاهده تاپیک
    سلام من این کد به 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;








    }



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




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


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

تاپیک های مشابه

  1. برنامه نویسی موازی
    نوشته شده توسط bpzone در بخش C#‎‎
    پاسخ: 9
    آخرین پست: دوشنبه 06 اردیبهشت 1395, 07:40 صبح
  2. آموزش: تازه های برنامه نویسی موازی در .NET 4.5
    نوشته شده توسط tooraj_azizi_1035 در بخش C#‎‎
    پاسخ: 0
    آخرین پست: شنبه 27 خرداد 1391, 14:23 عصر
  3. آموزش: مجموعه سورس های مربوط به برنامه نویسی موازی
    نوشته شده توسط alimanam در بخش VB.NET
    پاسخ: 0
    آخرین پست: دوشنبه 10 بهمن 1390, 23:39 عصر
  4. سوال در مورد ایجاد یک Application ساده با برنامه نویسی موازی
    نوشته شده توسط DrXoX1790 در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 1
    آخرین پست: دوشنبه 21 تیر 1389, 02:43 صبح
  5. کمک : برنامه نویسی موازی
    نوشته شده توسط nima_trade در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 11
    آخرین پست: پنج شنبه 19 آذر 1383, 00:43 صبح

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •