زبان برنامه‌نويسي cuda
صفحه 1 از 2 12 آخرینآخرین
نمایش نتایج: از شماره 1 تا 10 , از مجموع 20

موضوع: زبان برنامه‌نويسي cuda

  1. viunj آواتار ها
    viunj
    مدیر سابق
    Mar 2009
    9,904
    1,444
    تشکر شده : 5,203

    پیش فرض زبان برنامه‌نويسي cuda

    زبان برنامه‌نويسي CUDA
    تجربه برنامه‌نويسي موازي ساده

    پردازنده‌هاي مرکزي به‌عنوان مغز کامپيوترهاي امروزي، وظيفه اجراي دنباله‌اي از دستورات را دارند. بيشتر اين پردازنده‌ها داراي گونه‌اي از معماري هستند که در هر لحظه يک عمليات را بر يک داده انجام مي‌دهند (SISD1). دسته ديگري از پردازنده‌ها (SIMD2) وجود دارند که قادرند در هر پالس يک دستورالعمل را روي چندين داده انجام دهند. براي نمونه، پردازنده‌هاي واحد پردازش گرافيکي (GPU3) از اين نوع‌اند.



    اجراي يک دستور بر چندين داده به‌كمك چندين هسته صورت مي‌گيرد. واحدهاي پردازشگر گرافيكي امروزي بيش از 100‌هسته دارند که تمامي هسته‌هاي آنها متشابه‌اند. يک هسته GPU بسيار ساده‌تر از يک هسته پردازنده مرکزي است. يک GPU با n هسته قادراست يک دستور را روي بيش از n داده مختلف اجرا کند.

    اين قابليت براي اجراي برخي نخ‌ها4 با ويژگي خاص، بسيار مناسب است. براي مثال فرض کنيد مي‌خواهيم سينوس 100 عدد را محاسبه كنيم. اگر پردازنده مرکزي بخواهد اين كار را انجام دهد، 100بار بايد يک دستور را اجرا کند ولي GPU اين عمليات را تقريبا 100برابر سريع‌تر انجام مي‌دهد! تنها ويژگي که نخ‌ها بايد داشته باشند اين است که متشابه باشند. يعني بخواهند عمليات يکساني را روي داده‌هاي متفاوت انجام دهند.
    نوشتن برنامه‌اي که از GPUها براي انجام محاسبات گرافيکي استفاده کند، از طريق کتابخانه‌هاي Direct3D و OpenGL امکان‌پذير است که به‌ترتيب محصول مايکروسافت و SGI هستند. تلاش‌هايي براي به‌کاربردن GPU در محاسبات غيرگرافيکي نيز صورت گرفته است که تحت عنوان GPGPU5 شناخته مي‌شوند. GPGPU در واقع تکنيک استفاده از GPU براي انجام محاسبات عمومي (نه لزوما گرافيکي) است.
    NVIDIA و AMD، دو توليدکننده بزرگ GPU، تلاش خود را براي تحقق GPGPU از سال 2007 آغاز کردند. AMD FireStream و NVIDIA Tesla نمونه GPUهاي همه منظوره محصول اين دو شرکت هستند که براي برنامه‌نويسي و استفاده از قدرت اين GPUها مي‌توانيد به‌ترتيب از Stream SDK و CUDA SDK بهره ببريد.
    کنار هم قرار دادن GPU و CPU و تقسيم کار بين آنها، کارايي بسيار بالايي فراهم مي‌کند. اين تقسيم کار به اين صورت است که دنباله دستورات را CPU دنبال كند و هر جا كه نياز به انجام محاسبات موازي شد، کار را به GPU بسپارد.
    شرکت انويديا مدل CUDA6 را در سال 2007 با همين هدف معرفي کرد. كودا مدلي است براي پردازش موازي همه‌منظوره که در سطح نرم‌افزاري، شامل يک سري دستورالعمل و در سطح سخت‌افزار شامل موتور پردازش موازي در GPU است. براي برنامه‌نويسي با مدل كودا، برنامه‌نويسان مي‌توانند از زبان C که يکي از رايج‌ترين زبان‌هاي سطح بالا است، استفاده کنند و با کارايي عالي روي پردازنده مجهز به كودا اجرا كنند.
    اهداف كودا
    مدل كودا و نرم‌افزارهاي مرتبط آن با چندين هدف طراحي شده است:
    1- افزودن توزيع‌هاي کوچکي به زبان‌هاي برنامه‌نويسي استاندارد (مانند سي) که پياده‌سازي بي‌واسطه الگوريتم‌هاي موازي را ممکن مي‌سازد. منظور از پياده‌سازي بي‌واسطه، کاهش لايه‌هاي واسط بين سخت‌افزار و نرم‌افزار است. با كودا و زبان سي براي كودا، برنامه‌نويسان به‌جاي آن‌که درگير پيچيدگي‌هاي پياده‌سازي شوند، مي‌توانند بر الگوريتم‌هاي موازي‌سازي تمرکز داشته باشند.
    2- پشتيباني از پردازش ناهمگن، به‌نحوي که برنامه‌ها هم از CPU و هم GPU بهره مي‌برند. بخش‌هاي متوالي برنامه توسط CPU اجرا مي‌شوند و بخش‌هاي موازي توسط GPU. در عمل CPU و GPU واحدهاي مجزايي خواهند بود که حافظه جداگانه خود را دارند. اين پيکربندي اجازه مي‌دهد تا پردازش همزمان در هر يک از دو واحد، بدون تداخل صورت گيرد.
    3- GPUهاي مجهز به كودا صدها هسته دارند و مي‌توانند به‌صورت انتخابي هزاران نخ را اجرا کنند.
    پيش‌نيازهاي كودا
    براي به‌کاربردن كودا روي سيستم خود، نياز داريد که موارد زير روي سيستم نصب شده باشد:
    1- GPUمجهز به كودا: از جمله کارت‌هاي گرافيکي NVIDIA GeForce سري 8، 9 و Quadro و نيز کارت‌هاي Tesla.
    2- درايور كودا.
    3- نرم‌افزار كودا: اين بخش شامل دو بسته نرم‌افزاري است، CUDA Toolkit که شامل کتابخانه‌ها و توزيع ويژه زبان سي است و CUDA SDK که شامل نمونه کد و برنامه‌هايي به زبان سي است که از معماري كودا بهره مي‌برند.
    4- مايكروسافت ويژوال استوديو نگارش 2005 يا 2008 يا يکي از نسخه‌هاي مشابه مايكروسافت ويژوال C++ اكسپرس.
    كاربران كودا
    اگر از علاقه‌مند به کدنويسي موازي هستيد، با استفاده از معماري كودا ديگر لازم نيست درگير پياده‌سازي ايده‌هاي خود شويد و مي‌توانيد تمرکز خود را بر موازي‌سازي بگذاريد.
    اگر زبان سي را مي‌دانيد، نيازي به خريد کتابي براي يادگيري كودا نداريد و پس از نصب كودا مي‌توانيد از کتاب الکترونيکي موجود در بسته نرم‌افزاري يادگيري را آغاز کنيد.
    اگر از کاربران لينوکس هستيد، نيز نگران نباشيد تنها کافي است نرم‌افزارهاي فوق را براي توزيع لينوکس خود دريافت کنيد و gcc نسخه 4 به بالا نيز داشته باشيد.
    گسترش كودا
    هم‌اكنون برنامه‌نويسان و شرکت‌هاي بزرگي به كودا گرايش پيدا کرده‌اند. از جمله اين شرکت‌ها Mathworks، سازنده نرم‌افزار (به‌گفته طراحانش زبان برنامه‌نويسي) Matlab است که براي بهينه‌سازي هرچه بيشتر کدهاي خود به كودا روي آورده است. نمونه کدها و برنامه‌هايي از شرکت‌هاي مختلف (از جمله گوگل) به اين زبان در سايت انويديا موجود است. به‌گفته شرکت انويديا در حال حاضر كودا در بيش از 35دانشگاه معتبر جهان تدريس مي‌شود.
    براي اطلاعات بيشتر و دريافت نرم‌افزارها و درايورهاي ذکر شده به‌صورت رايگان، به سايت زير مراجعه كنيد:
    فقط کاربران ثبت نام شده میتوانند لینک های انجمن را مشاهده کنند. ]
    منابع
    [1] فقط کاربران ثبت نام شده میتوانند لینک های انجمن را مشاهده کنند. ]
    /compute/cuda/2_1/toolkit/docs/NVIDIA_
    CUDA_Programming_Guide_2.1.pdf
    [2] فقط کاربران ثبت نام شده میتوانند لینک های انجمن را مشاهده کنند. ]
    [3] David A. Patterson; John L. Hennessy,
    Computer Organization and Design: the
    Hardware/Software Interface, 3rd Edition,
    Morgan Kaufmann, 2007.
    پي‌نوشت
    1. Single Instruction Single Data
    2. Single Instruction Multiple Data
    3. Graphic Processing Unit
    4. Threat
    5. General Purpose GPU
    6. Compute Unified Device Architecture
    احمد لشگر

    زنده باد ایران و ایرانی
    #1 ارسال شده در تاريخ 30th August 2009 در ساعت 17:19

  2. ahmadabdali آواتار ها
    ahmadabdali
    کاربر سایت
    Apr 2014
    2
    0
    تشکر شده : 0

    پیش فرض

    فقط کاربران ثبت نام شده میتوانند لینک های انجمن را مشاهده کنند. ]


    برنامه نویسی Cuda یک سبک کاملا جدید از برنامه نویسی موازی می باشد که بجای اینکه الگوریتم موازی در cpu اجرا شود در gpu کارت گرافیک انجام میگیرد در واقع از امکانات سخت افزاری کارت گرافیک به خوبی استفاده میکنیم تا بار محاسباتی cpu کاهش یابد تحقیقات نشان داده که زمان اجرا در Gpu در اکثر مواقع از cpu کمتر است . با توجه به اینکه در تعداد زیادی از دانشگاه های کشور cuda وارد عرصه تحقیقاتی شده است که یک حیطه بکر و تازه برای تحقیقات است . ام متاسفانه عدم وجود منابع کافی حتی لاتین و فقدان منابع فارسی و دشواری برنامه نویسی این سبک هر ترم به تعداد مشخصی پروژه برنامه نویسی Cuda را می پذیریم . لیست آموزش Cuda
    - نصب و راه اندازی Cuda در کامپایلر های مشهور از جمله Visual Studio 2010 &2012
    - آموزش معماری و سخت افزار GPU
    - آموزش فریم ورک Cuda و دستورات Cuda در محیط ++VC
    - آموزش فریم ورک Cuda و دستورات Cuda در محیط C#.net
    - آموزش بکار گیری فایل های ptx حاصل از Cuda و بکار گیری آنها در matlab
    - آموزش Mex و بکار گیری آن در مطلب
    - آشنای با کتابخانه thrust برای سرعت بخشیدن به برنامه نویسی GPU با Cuda
    - آشنایی با امکانات matlab برای کار با GPU
    آشنایی با امکانات CUDAFY.NET برای کار با GPU
    پروژه های پیشنهادی که با Cuda پیاده سازی کرده ایم
    - کتابخانه GPUMLIB
    - کتابخانه SVMLIB
    - الگوریتم ژنتیک GENATIC با CUDA
    - الگوریتم کرم شب تاب Fire Fly با Cuda
    - الگوریتم کلونی مورچه ACO با Cuda
    - الگوریتم ذرات و پرندگان PSO با Cuda
    - الگوریتم فاخته Cuckoo با Cuda
    -الگوریتم فروشنده دوره گرد TSP با Cuda
    - الگوریتم وارشال Warshal با Cuda
    - الگوریتم خفاش Bat با Cuda
    - الگوریتم گرده افشانی گل ها با Cuda
    -الگوریتم رقابت استعماری با Cuda
    -الگوریتم کلونی زنبور ها با Cuda
    -الگوریتم جستجوی هارمونی با Cuda
    و ...



    آموزش برنامه نویسی پردازش موازی بوسیله CUDA تکنولوژی برنامه نویسی GPU از NVIDIA ,Parallel Computing with CUDA, آموزشی برنامه نویسی CUDA و CUDA C برای استفاده از امکانات و قابلیت های GPU های NVIDIA را به خوبی خواهید آموخت,آموزش پردازش موازی با استفاده از , الگوریتم خفاش در Cuda , الگوریتم فاخته یا Cuckoo در Cuda ,الگوریتم موازی cuckoo ,الگوریتم موازی PSO ,الگوریتم موازی کرم شب تاب , الگوریتم ژنتیک در Cuda , الگوریتم گرده افشانی گل ها در Cuda , انجام پروژه ها و پایان نامه های ارشد , انجام پروژه های Cuda , انجام پروژه های GPU , انجام پروژه های موازی , برنامه نویسی Cuda , برنامه نویسی GPU , برنامه نویسی کودا , نصب cuda در متلب Matlab , نصب و راه اندازی Cuda , پروژه FireFly در cuda ,پروژه PSO در Cuda , پروژه الگوریتم کرم شب تاب در Cuda GPU , کتابخانه gpumlib و برنامه نویسی Cuda
    ویرایش توسط ´•.Saeid.•` : 3rd December 2015 در ساعت 11:42
    #2 ارسال شده در تاريخ 27th April 2014 در ساعت 14:49

  3. saeed_smco آواتار ها
    saeed_smco
    کاربر سایت
    Nov 2010
    1
    1
    تشکر شده : 0

    پیش فرض

    سلام
    من نیاز به آموزش یا برنامه نویسی cuda دارم
    کسی میتونه کمکم کنه؟
    فقط کاربران ثبت نام شده میتوانند لینک های انجمن را مشاهده کنند. ]
    09303631436
    #3 ارسال شده در تاريخ 31st December 2014 در ساعت 10:56

  4. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    کودا از دیدگاه اصول طراحی زبان زبان کودا بر پایه ی ++c/c طراحی شده است. extension های اضافه شده مجموعه‌ای کوچک هستند که heterogeneous programming را فراهم می کنند. از طرف دیگر API کودا برای مدیریت حافظه و .. بسیار راحت و کاربر پسند می باشد.همگی اینها عواملی هستند که باعث شده تا کودا دو اصل information hiding و abstraction را رعایت کند. استفاده از قدرت پردازش GPU در حل مسائلی که در آن ها حجم اطلاعات و کار انجام شده زیاد است اما استقلال داده ای نسبی وجود دارد باعث شد تا برنامه نویسان به برنامه نویسی برای پردازنده های گرافیکی روی بیاورند اما از آنجا که هر پردازنده معماری خاص خود را داشت، کدهای زده شده وابسته به ماشین بودند و portability نداشتند اما با طراحی زبان کودا کدها با استفاده از این زبان زده می شدند و مستقل از معماری پردازنده، برنامه نویس می توانست فرض هایی برای تعداد ریسه ها در بلاک ها و تعداد بلاک ها در گریدها و .. داشته باشد و mapping بین این فرض ها و معماری ماشین را کودا انجام می داد این ویژگی باعث شد تا کودا اصل portability را رعایت کند.اما کودا برای تعداد ریسه ها در یک بلاک و تعداد بلاک ها در یک گرید سقف قایل شده است و کاربر برنامه نویس باید این حداکثرها را بداند در نتیجه اصل zero-one-infinitely در این مورد نقض شده است.دستورهای اضافه شده در کودا به گونه ای هستند که مشابه دستوراتی از C هستند که کاربرد مشابه دارند مثلا دستور های cudaMalloc، cudaMemcpy، cudaFree برای مدیریت حافظه ی GPU در کودا هستند و free, malloc و memcpy هم مدیریت حافظه در زبان c را پیاده سازی می کنند یعنی کارهای مشابه با دستورهای مشابه انجام می شوند که این همان اصل static consistency است.برای اجرای کد در GPU پردازنده ی CPU باید داده ها را به حافظه ی GPU منتقل کند و نتابج حاصل را به حافظه ی CPU منتقل کند که این overhead برای هر برنامه ای که روی GPU اجرا می شود وجود دارد و این یعنی کاربر هزینه ای (هزینه ی انتقال) به جز هزینه ی پردازش مورد نیاز را هم باید بپردازد که این موضوع ناقض اصل localized cost است.

    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #4 ارسال شده در تاريخ 31st December 2014 در ساعت 13:15

  5. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    نصب کودا بر اوبونتو و اجرای آن
    ‌فرآيند نصب کودا (حداقل روي لينوكس) دست کمي از برنامه‌نويسي براي آن ندارد؛ در حقيقت نصب آن روي هر سيستم لينوکسي‌اي مي‌تواند به عملياتي بسيار طاقت فرسا تبديل شود. در اين بخش سعي خواهيم کرد اصول کلي نصب کودا 3,0 را روي اوبونتوي 10,04 بيان کنيم. ضمن اين‌كه فرآيند نصب کودا روي لينوکس به صورت کلي از بخش‌هاي زير تشکيل شده است:
    -1نصب Package‌هاي مورد نياز
    قبل از نصب کودا دقت كنيد که بايد اين پکيج‌ها روي سيستم عاملتان موجود باشد‌: build-essential ، libglut3-dev، libXi-dev و libXmu-dev.
    -2نصب Developer Driver
    براي نصب اين پکيج راه‌هاي مختلفي وجود دارد. يکي دانلود آن از سايت Nvidia، اجرا كردن آن با دستور chmod +x و اجراي آن در حالت Root و البته پس از اين‌که
    X Server فعليتان را متوقف ساختيد. براي متوقف ساختن X Server مي‌توانيد از اين دستور استفاده كنيد‌:

    sudo /etc/init.d/gdm stop
    البته بايد پس از نصب درايور، به فايل /etc/modprobe.d/blacklist.Conf رفته و خطوط زير را به آن اضافه کنيد‌:

    blacklist vga16fb
    blacklist nouveau
    blacklist rivafb
    blacklist nvidiafb
    blacklist rivatv

    همان طور که گفته شد، راه‌هاي ديگري نيز براي نصب درايور وجود دارد که استفاده از آن‌ها در پيش‌برد كار شما بي تأثير نخواهد بود. يکي از آن‌ها استفاده از apt-get خود اوبونتو است. کافي است تايپ کنيد‌:

    sudo apt-get install nvidia-current

    با استفاده از اين دستور نسخه مناسب درايور براي سيستم شما نصب خواهد شد.
    در پايان هر دو روش نيز دستور زير را وارد كنيد:

    sudo modprobe nvidia

    -3نصب Toolkit کودا
    براي اين کار کافي است پکيج مربوطه را از سايت NVidia دانلود کرده، آن را با chmod +x اجرايي کرده و سپس در حالت root آن را اجرا كنيد.
    -
    4تنظيم متغيرهاي محيطي
    کودا به تنظيم دو متغير محيطي نياز دارد. براي اين کار فايل etc/environment را باز کرده و به متغير محيطي PATH مقدار،/usr/local/cuda/bin و به مـتغير محيــطي /usr/local/cuda/libLD_LIBRARY_PATH، را اضافه كنيد. البته اين در حالتي است که کودا را هنگام نصب در آدرس پيش فرض آن، يعني/usr/local/cuda نصب کرده باشيد. در غيراين صورت آدرس‌ها را مطابق با آدرس نصب خودتان تغيير دهيد

    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #5 ارسال شده در تاريخ 31st December 2014 در ساعت 13:15

  6. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    نصب كيت توسعه کودا و اجراي مثال‌ها
    SDK کودا شامل مثال‌هاي مفيد فراواني است که مي‌توانيد از آن‌ها استفاده كنيد. پس از دانلود اين SDK از سايت NVidia، آن را اجرا کرده و با مشخص کردن آدرس toolkit کودا و آدرس نصب SDK کار شما به پايان مي‌رسد. توجه کنيد که براي نصب و اجراي اين SDK توسط کودا 3 بايد از gcc و g++ نسخه 4,3 استفاده کنيد. در صورتي که سيستم شما gcc نسخه 4,4 دارد و قصد نداريد که آن را به 4,3 Downgrade کنيد (مانند وضعيتي که من با آن مواجه بودم) بايد يک سري تنظيمات اضافي انجام دهيد. براي اجراي مثال‌هاي SDK در دايرکتوري مربوط به آن به پوشه C رفته و دستورsudo make را تايپ کنيد. در ادامه با مراجعه به C/bin/linux/release مي‌توانيد فايل‌هاي اجرايي را مشاهده كنيد.براي کامپايل يک کد کودا مي‌توانيد از دستور nvcc نيز استفاده كنيد که فايل کوداي شما را کامپايل کرده و خروجي را به صورت فايل .out توليد مي‌كند.


    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #6 ارسال شده در تاريخ 31st December 2014 در ساعت 13:16

  7. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    مثال نخست: جمع دو بردار
    پياده‌سازي اين مثال در کد اول آورده شده است.
    1- در اين مثال دو بردار به اندازه دلخواه توليد شده و با اعداد تصادفي پر مي‌شوند. سپس هسته VecAdd اين دو بردار را به صورت موازي جمع مي‌کند. در واقع کد اين مثال کاملاً گويا بوده و به توضيح اضافي چنداني نياز ندارد. پس تنها به ذکر توضيح بعضي از بخش‌ها مي‌پردازيم.
    2-پياده سازي تابع checkCUDAError ديگر در اينجا ذكر نشده است. زيرا در کد ارائه شده در هفته قبل، پياده سازي مربوط به آن را بيان‌كرديم. استفاده از يک تابع جداگانه براي آزاد كردن حافظه و خروج از برنامه نيز از ديگر تکنيک‌هاي ساده‌اي است که عموماً در برنامه‌هاي کودا رعايت مي‌شود و منطق کد شما را واضح تر مي‌كند
    .
    #include
    float* h_A,h_B,h_C,d_A,d_B,d_C;
    void Cleanup(void);
    void RandomInit(float*, int);
    void checkCUDAError(const char *);
    __global__ void VecAdd(const float* A, const float* B, float* C, int N){
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < N)
    C[i] = A[i] + B[i];
    }
    int main(int argc, char** argv){
    int N = 500000;
    size_t size = N * sizeof(float);
    h_A = (float*)malloc(size);
    h_B = (float*)malloc(size);
    h_C = (float*)malloc(size);
    srand(123);
    RandomInit(h_A, N);
    RandomInit(h_B, N);
    cudaMalloc((void**)&d_A, size);
    cudaMalloc((void**)&d_B, size);
    cudaMalloc((void**)&d_C, size);
    cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
    int threadsPerBlock = 256;
    int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
    VecAdd<<>>(d_A, d_B, d_C, N);
    cudaThreadSynchronize();
    checkCUDAError(«kernel launch failure»);
    cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
    Cleanup();
    }
    void Cleanup(void){
    cudaFree(d_A);
    cudaFree(d_B);
    cudaFree(d_C);
    free(h_A);
    free(h_B);
    free(h_C);
    cudaThreadExit();
    exit(0);
    }
    void RandomInit(float* data, int n){
    for (int i = 0; i < n; ++i)
    data[i] = rand() / (float)RAND_MAX;
    }


    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #7 ارسال شده در تاريخ 31st December 2014 در ساعت 13:16

  8. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    مثال نخست: ضرب داخلی دو بردار

    اين مثال نمونه بسيار خوبي از نحوه نوشتن برنامه را براي کودا نشان مي‌دهد. در اين برنامه به تعداد دلخواهي زوج بردار در اختيار داريم و مي‌خواهيم ضرب داخلي اين زوج بردارها را حساب کنيم. زوج بردار در اين جا به معناي دو بردار هم اندازه از اعداد Float بوده و ضرب داخلي نيز همان‌طور که مي‌دانيد به معناي ضرب مؤلفه در مؤلفه دو بردار و جمع اين مقادير با يکديگر است. به اين ترتيب، با داشتن N زوج بردار خروجي ما نيز بايد آرايه‌اي به اندازه N باشد. به بيان ديگر، اگر A و B آرايه‌اي از بردارها باشند، C به صورتي تعريف مي‌شود که C[i]=A[i].B[i] علامت ضرب داخلي است. به دليل شباهت پياده‌سازي توابع CheckCUDAError، Cleanup و RandomInit به پياده‌سازي‌هاي قبلي در اين مقاله، اشاره‌اي به آن‌ها نشده است. توجه کنيد که در‌باره Cleanup بايد نام متغيرها را با نام متغيرهاي اين مسئله جايگزين کنيد. دو کد ديگر عيناً يکي هستند. در ضمن بهتر بود به جاي دسترسي به متغيرهاي عمومي‌اي مانند VECTOR_N و ELEMENT_N آن‌ها به صورت آرگومان به هسته فرستاده مي‌شدند تا دسترسي به آن‌ها به صورت محلي انجام پذيرد. اما براي سادگي کد اين ملاحظات در نظر گرفته نشده است
    .


    #include
    #include
    void checkCUDAError(const char *);
    void Cleanup(void);
    void RandomInit(float*, int);
    const int VECTOR_N = 256;
    const int ELEMENT_N = 4096;
    const int DATA_N = VECTOR_N * ELEMENT_N;
    const int DATA_SZ = DATA_N * sizeof(float);
    const int RESULT_SZ = VECTOR_N * sizeof(float);
    float *h_A, *h_B, *h_C, *d_A, *d_B, *d_C;
    #define ACCUM_N 1024
    __global__ void scalarProdGPU(float *d_C,float *d_A,float *d_B){
    __shared__ float accumResult[ACCUM_N];
    for(int vec = blockIdx.x; vec < VECTOR_N; vec += gridDim.x){
    int vectorBase = ELEMENT_N*vec;
    int vectorEnd = vectorBase + ELEMENT_N;
    for(int iAccum = threadIdx.x; iAccum < ACCUM_N; iAccum += blockDim.x){
    float sum = 0;
    for(int pos = vectorBase + iAccum; pos < vectorEnd; pos += ACCUM_N)
    sum += d_A[pos] * d_B[pos];
    accumResult[iAccum] = sum;
    }
    for(int stride = ACCUM_N / 2; stride > 0; stride >>= 1){
    __syncthreads();
    for(int iAccum = threadIdx.x; iAccum < stride; iAccum += blockDim.x)
    accumResult[iAccum] += accumResult[stride + iAccum];
    }
    if(threadIdx.x == 0) d_C[vec] = accumResult[0];
    }
    }
    int main(int argc, char **argv){
    h_A = (float *)malloc(DATA_SZ);
    h_B = (float *)malloc(DATA_SZ);
    h_C = (float *)malloc(RESULT_SZ);
    cudaMalloc((void **)&d_A, DATA_SZ);
    cudaMalloc((void **)&d_B, DATA_SZ);
    cudaMalloc((void **)&d_C, RESULT_SZ);
    srand(123);
    RandomInit(h_A, DATA_N);
    RandomInit(h_B, DATA_N);
    cudaMemcpy(d_A, h_A, DATA_SZ, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, DATA_SZ, cudaMemcpyHostToDevice);
    scalarProdGPU<<<128, 256>>>(d_C, d_A, d_B);
    cudaThreadSynchronize();
    checkCUDAError(«invoking»);
    cudaMemcpy(h_C, d_C, RESULT_SZ, cudaMemcpyDeviceToHost);
    Cleanup();
    }

    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #8 ارسال شده در تاريخ 31st December 2014 در ساعت 13:16

  9. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    بخش Main برنامه به توضيح چنداني نياز ندارد. تنها توجه کنيد که هسته براي تعداد 128 بلاک و 256 رشته‌پردازشي به ازاي هر بلاک فراخواني شده است. در‌باره تعريف اوليه ثابت‌ها در ابتداي کد نيز لازم است تا معناي هر ثابت مشخص شود. VECTOR_N تعداد زوج بردارهايي است که بايد عمليات ضرب داخلي روي آن‌ها انجام شود. ELEMENT_N نيز تعداد المنت‌ها يا مؤلفه‌هاي هر بردار است. به اين ترتيب، تعريف ثابت‌هاي ديگر نيز مشخص مي‌شود. در اين ميان ACCUM_N نيز وجود دارد که با بررسي کد هسته آن را توضيح مي‌دهيم.

    در خط نخست تعريف هسته يک آرايه اشتراکي براي تمام رشته‌هاي پردازشي يک بلاک با نام AccumResult تعريف شده است. براي توضيح اين آرايه بايد نحوه تقسيم بندي کارها به صورت موازي را توضيح داد. همان‌طور که ذکر شد اين هسته با 128 بلاک و 256 رشته‌پردازشي به ازاي هر بلاک اجرا شده است. با توجه به اين‌که تعامل ميان بلاک‌هاي مختلف توصيه نمي‌شود، بهتر است تا جاي ممکن رشته‌هاي پردازشي که کارهاي مشابه انجام مي‌دهند، در يک بلاک قرار گيرند. به طور طبيعي بلافاصله اين ايده به ذهن مي‌رسد که ضرب يک زوج بردار بايد توسط رشته‌هاي پردازشي يک بلاک انجام شود. يعني بايد روشي پيدا کرد که زوج بردارها را به بلاک‌ها نسبت دهيم.


    اين همان کاري است که For اول هسته انجام مي‌دهد. يعني مشخص کردن بردار مورد‌نظر با blockIdx.x يا شناسه يک بلاک. پس مقدار متغير vec براي رشته‌هاي پردازشي که در داخل يک بلاک قرار دارند، يکسان است. توجه کنيد که ما 256 زوج بردار داشتيم، اما فقط 128 بلاک داريم. پس هر بلاک بايد دو زوج بردار را برعهده بگيرد. اين عمل با نحوه اضافه شدن vec در For مشخص شده است. چون هر بار vec به اندازه gridDim.x يا همان 128 زياد مي‌شود. پس به عنوان مثال، بلاک شماره يك، زوج بردار شماره 1 و 129 را در هم ضرب خواهد کرد. در مرحله بعد نيز مکان شروع و پايان بردار در حافظه تعيين مي‌شود. حال بايد ضرب يک زوج بردار را بين رشته‌هاي پردازشي يک بلاک پخش کنيم.


    به اين ترتيب، هر رشته‌پردازشي تنها مسئول ضرب داخلي بخشي از دو بردار در يکديگر است. اينجا است که ACCUM_N مورد استفاده قرار مي‌گيرد. با نگاه به For دوم مشخص مي‌شود که اين پياده‌سازي براي ضرب دو بردار 4096 مؤلفه‌اي در يکديگر از 256 رشته‌پردازشي استفاده مي‌كند، يعني هر رشته‌پردازشي مسئول ضرب شانزده جفت مؤلفه در هم است. متغير iAccum که در بدنه For به کار رفته است هربار به اندازه blockDim.x يا تعداد رشته‌هاي پردازشي موجود در هربلاک (256) اضافه مي‌شود.حلقه For بعدي همان جايي است که عمليات ضرب انجام مي‌شود. براي توضيح بهتر اين بخش فرض کنيد که با رشته‌پردازشي شماره يک وارد آن شده‌ايد. طبق For نخست متغير iAccum در طول اجراي حلقه مقادير 1، 257، 513 و 769 را اختيار خواهد کرد. براي مقدار نخست (1) اين مؤلفه‌ها دو به دو در يکديگر ضرب شده و جمع آن‌ها نگه داشته مي‌شود‌: 1,1 و 1025,1025 و 2049,2049 و 3073,3073.اين کار براي ديگر مقادير iAccum نيز انجام مي‌شود. در پايان هر مرحله نيز نتيجه accumResult[iAccum] ثبت مي‌شود. با توجه به اين‌که ضرب هر چهار زوج مؤلفه در يک خانه آرايه نگه‌داري مي‌شود، پس طبيعي است که آرايه‌اي با طول 1024 براي ذخيره‌سازي ضرب دو بردار 4096 مؤلفه‌اي کافي است.



    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #9 ارسال شده در تاريخ 31st December 2014 در ساعت 13:17

  10. babiz آواتار ها
    babiz
    مدیر سابق
    Nov 2011
    84,119
    31,889
    تشکر شده : 43,718

    پیش فرض

    حال يک سري مقدار در آرايه AccumResult داريم که بايد تمام آن‌ها را با يکديگر جمع کنيم. براي اين کار بهترين روش عمل به روش درختي است ( درخت برعکس). براي اين کار از دو For استفاده شده است. اولي از 512 شروع کرده و درهر مرحله متغير حلقه يعني stride را يک واحد به سمت راست شيفت مي‌دهد. پس مقادير بعدي 256، 128 و ... خواهند بود. نکته بسيار مهم در پياده‌سازي هسته روتين Syncthreads‌اي که در خط بعدي فراخواني شده است. اين باعث مي‌شود تا در هر Level از درخت، رشته‌هاي پردازشي منتظر شوند تا کارهاي قبلي بقيه رشته‌هاي پردازشي تمام شده و همه به اين نقطه برسند.
    زيرا تنها در اين حالت است که مي‌توان به درست بودن جمع درختي مقادير مطمئن شد. در سطح نخست درخت، For آخر حداکثر دو بار اجرا شده و براي بقيه سطوح حداکثر يک بار. به اين ترتيب، مقادير دو به دو با يکديگر جمع شده و در خانه‌اي با انديس کوچک‌تر ذخيره مي‌شوند تا جايي که Stride برابر يک مي‌شود و For آخر تنها براي رشته‌پردازشي شماره صفر اجرا مي‌شود. در پايان اين حالت AccumResult[0] شامل جمع تمام عناصر آرايه اوليه AccumResult است و به همين دليل مقدار آن نيز در d_C[vec] ذخيره مي‌شود.اين مثال نشان مي‌دهد که چگونه براي مسئله‌اي به اين سادگي پياده‌سازي به نسبت پيچيده‌اي را براي اجرا به وسيله کودا مي‌توان انجام داد. اين موضوع با تمام زيبايي‌هايش يک زنگ خطر براي توسعه دهندگان علاقه‌مند به کودا محسوب مي‌شود و آن اين است که‌: «هر چه قدر هم که کودا معماري آسان و روشني به نظر آيد، از ياد نبريد که پياده‌سازي برنامه‌ها براي اجرا روي پردازنده‌هاي گرافيکي عموماً دشوارتر از پياده‌سازي سريال آن‌ها است.»

    وبگاه تاریخ ما : tarikhema.org


    کانال تلگرام تاریخ ما : t.me/tarikhema
    #10 ارسال شده در تاريخ 31st December 2014 در ساعت 13:17

صفحه 1 از 2 12 آخرینآخرین

موضوعات مشابه

  1. تاریخ و فرهنگ آذربایجان غربی
    توسط Admin در انجمن استان آذربایجان غربی
    پاسخ ها: 23
    آخرين نوشته: 26th July 2013, 11:58
  2. تاریخ و فرهنگ استان مرکزی
    توسط Admin در انجمن استان مركزي
    پاسخ ها: 6
    آخرين نوشته: 6th January 2012, 23:26
  3. مختصری راجع به شعر و شاعری...
    توسط Alone GirL در انجمن آرشیو بخش ادبیات
    پاسخ ها: 50
    آخرين نوشته: 17th May 2011, 20:50
  4. اهمیت تاریخی زبان دری ـ فارسی درهند
    توسط Admin در انجمن هندوستان و پاکستان
    پاسخ ها: 0
    آخرين نوشته: 22nd July 2008, 21:27

علاقه مندی ها (Bookmarks)

مجوز های ارسال و ویرایش

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