وبلاگ شخصی مرتضی طلوع

ضرب ماتریس به صورت موازی

يكشنبه, ۱۰ بهمن ۱۳۹۵، ۰۸:۳۸ ق.ظ

معرفی

می‌خواهیم ضرب دو ماتریس را به روش سری و همچنین سه روش موازی  انجام دهیم و نتیجه را مقایسه کنیم:

  1. Open-MP
  2. MPI
  3. CUDA

در اینجا هدف آموزش یا معرفی سه روش فوق نیست. فرض بر این است که شما با برنامه‌نویسی با سه روش فوق آشنا هستید. در اینجا هدف کامپایل و اجرای برنامه نوشته شده در لینوکس است. دستورات زیر بر روی توزیع Debian 8.6 و Mint 18 اجرا و تست شده‌اند.

Serial

حالت سریال کدنویسی و کامپایل و اجرای بسیار ساده و روتینی دارد. کافیست کامپایلر gcc  را نصب داشته باشید. اگر کد خود را در فایلی به نام serial.cpp نوشته‌اید کافیست با دستور زیر آن را کامپایل کنید:

g++ serial.cpp -o serial

چنانچه‌ کامپایل با موفقیت اتجام شد فایل باینری serial ساخته می‌شود که به راحتی قابل اجراست:

./serial

Open-MP

در این روش همان برنامه سریال را با اندک تغییر میتوان موازی کرد. برای اینکار از کامپایلر دایرکتیوهای open-mp استفاده می‌کنیم. 

برای کامپایل کافیست پارامتر openmp  را به خط فرمان کامپایلر اضافه کنیم. مثلا اگر نام فایل حاوی سورس omp.cpp  باشد با این دستور می‌توان آن را کامپایل و لینک کرد:

g++ -openmp omp.cpp -o omp-mp

در صورتی که سی‌پی‌یو شما AMD است از دستور fopenmp استفاده کنید.
برای اجرا هم کافی‌ست نام فایل اجرایی را بنویسیم:

./omp

MPI

برنامه MPI هم نحوه کامپایل متفاوتی دارد و هم نحوه اجرای آن فرق دارد. برای کامپایل باید بسته mpi-default-dev نصب باشد و با دستور mpicc یا mpic++ برنامه کامپایل شود:

sudo apt-get install mpi-default-dev
mpic++ mpi.cpp -o mpi

برای اجرا باید بسته mpi-default-bin نصب باشد و با دستور mpirun برنامه اجرا شود:

apt-get install mpi-default-bin
mpirun -n 4 ./mpi

در این مثال تعداد پردازنده‌ها ۴ است.

برای داشتن شرایط واقعی بایستی به صورت توزیع شده با چند تا سیستم برنامه اجرا شود. برای اینکار فایل باینری را بر روی همه کلاینتها ایجاد کنید. اگر مشخصات کلاینتها با سرور یکی است، از همان فایل باینری سرور می‌توانید استفاده کنید. وگر نه باید در هر کلاینت با دستور mpic++ فایل باینری مخصوص به خود را درست کنید.

برای سهولت مسیر فایل باینری روی سرور با همه کلاینتها یکسان باشد. مثلا اگر روی سرور فایل اجرایی در مسیر 

/home/mt/matrix/mpi

قرار دارد، فایل اجرایی با همین نام mpi روی همه کلاینتها در همین مسیر قرار گیرد.

همچنین نام کاربری مورد استفاده روی سرور، بر روی همه کلاینتها ایجاد شود و ضمنا با کپی کلید عمومی سرور بر روی کلاینتها اجازه لاگین ssh از سرور به کلاینتها را بدهید. برای درست کردن یک کلید عمومی/خصوصی از دستور 

ssh-keygen -t rsa

استفاده کنید. سپس برای کپی کلید عمومی سرور بر روی هر کلاینت دستور زیر را در سرور اجرا کنید:

ssh-copy-id user@client

که در آن user نام کاربری و client آی‌‌پی کلاینت است.

اکنون آی‌پی کلاینتها را در فایلی به اسم مثلا hostfile بنویسید (در هر خط یک آی پی). آخرین مرحله اجرای فایل mpi است به طوری که با پارامتر hostfile اسم فایل حاوی آی‌پی کلاینتها را به آن معرفی کرده‌اید:

mpirun --hostfile hostfile ./mpi

MPI on ARM

برای اجرا بر روی اندروید می‌توان از نرم افزار termux استفاده کرد. با کمک این نرم افزار می‌توانید دستورات را بر روی لینوکس گوشی خود اجرا کنید. همچنین بسیاری از پکیج‌ها را بر روی مخازن خود برای ARM آماده کرده است.

ولی متاسفانه پکیجهای mpi وجود ندارد. برای کامپایل mpi از روی سورس پس از نصب gcc و دانلود سورس mpi فایل configure باید اجرا شود که با خطا مواجه میشود. اولا باید /bin/sh و /bin/rm و ... به /system/bin/sh و /system/bin/rm و ... تغییر پیدا کند. ثانیا از انجایی که از مجوز نوشتن در مسیر tmp خطا می‌گیرد، با کمک لینک

Problems with here docs/strings in Android implementations of bash/mksh

مسیر tmp اصلاح شد:

export TMPDIR=/sdcard/.tmp/$RANDOM
mkdir -p $TMPDIR

سپس باید configure اجرا شود

./configure --build=arm-linux-gnueabi --host=armv7-linux-gnueabi \
--disable-mpi-fortran \
--disable-mpi-cxx --prefix=`pwd`/install \
--enable-shared --enable-static \
--disable-mmap-shmem --disable-posix-shmem --disable-sysv-shmem \
--disable-dlopen

ولی خطا گرفت و کار نکرد!

checking host system type... Invalid configuration `armv7-linux-gnueabi': machine `armv7' not recognized
configure: error: /data/data/com.termux/files/usr/bin/sh config/config.sub armv7-linux-gnueabi fa

برای همین تصمیم گرفتم cross compiling انجام بدم. با کمک لینک

Cross compile for ARM

دو بسته g++-arm-linux-gnueabi و binutils-arm-linux-gnueabi را نصب کردم:

sudo apt install g++-arm-linux-gnueabi

ولی هنوز به نتیجه نرسیده‌ام!

CUDA

استفاده از GPU برای کارهای محاسباتی و به طور کلی غیر از گرافیکی که بناست خروجی کار به حافظه سیستم برگردد را  GPGPU (General Purpose GPU) میگویند. برای اینکار اولا باید درایور کارت گرافیک برای GPGPU نصب باشد. ثانیا ابزار نرم افزاری کار شامل کامپایلر را نصب کنید.

در این سایت مراحل کار برای نصب CUDA توضیح داده شده است:

http://matrivian.github.io/linux/2016/04/28/Install-Cuda.html

download cuda-repo-ubuntu1604-8-0-local_8.0.44-1_amd64-deb (1.9 GB by using VPN)

sudo dpkg -i cuda-repo-ubuntu1604-8-0-local_8.0.44-1_amd64-deb

sudo apt-update

sudo apt install cuda

  • مرتضی طلوع

CUDA

Linux Mint

MPI

OpenMP

نظرات (۰)

هیچ نظری هنوز ثبت نشده است
ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی