প্রথমত, সঠিক উত্তরটি নির্ভর করে: (1) ব্যবহার, অর্থাৎ ফাংশন ইনপুট আর্গুমেন্ট, (2) এমপিআই বাস্তবায়ন গুণমান এবং বিশদ এবং (3) আপনি যে হার্ডওয়্যারটি ব্যবহার করছেন তা। প্রায়শই, (2) এবং (3) সম্পর্কিত হয় যেমন হার্ডওয়ার বিক্রেতা যখন তাদের নেটওয়ার্কের জন্য এমপিআইকে অনুকূল করে।
সাধারণভাবে, এমপিআই সংগ্রহগুলি ছোট বার্তাগুলির জন্য ফিউজ করা ভাল, যেহেতু প্রারম্ভকালীন ব্যয়গুলি অনানুষ্ঠানিক হতে পারে এবং কলগুলির মধ্যে গণনা সময়ের মধ্যে পার্থক্য থাকলে সামঞ্জস্য অবরুদ্ধকরণের দ্বারা সংযুক্ত সিঙ্ক্রোনাইজেশন হ্রাস করা উচিত। বৃহত্তর বার্তাগুলির জন্য, লক্ষ্যটি পাঠানো হচ্ছে এমন পরিমাণের পরিমাণ হ্রাস করা উচিত।
উদাহরণস্বরূপ, তাত্ত্বিকভাবে, অনুসরণ করার MPI_Reduce_scatter_block
চেয়ে ভাল হওয়া উচিত , যদিও প্রাক্তনটি প্রায়শই পরবর্তীকালের ক্ষেত্রে প্রয়োগ করা হয়, যেমন কোনও আসল সুবিধা নেই। এমপিআইয়ের বেশিরভাগ বাস্তবায়নের ক্ষেত্রে প্রয়োগের গুণমান এবং ব্যবহারের ফ্রিকোয়েন্সিগুলির মধ্যে একটি সম্পর্ক রয়েছে এবং বিক্রেতারা স্পষ্টতই সেই ফাংশনগুলিকে অনুকূল করেছেন যার জন্য এটি মেশিন চুক্তি দ্বারা প্রয়োজনীয়।MPI_Reduce
MPI_Scatter
অন্যদিকে, যদি কোনও একটি ব্লু জিনে থাকে তবে MPI_Reduce_scatter_block
ব্যবহার করা MPI_Allreduce
, যা সংযোগের চেয়ে আরও বেশি যোগাযোগ করে MPI_Reduce
এবং MPI_Scatter
সংঘবদ্ধ করে তোলে তা আসলে কিছুটা দ্রুত। এটি আমি সম্প্রতি আবিষ্কার করেছি এবং এটি এমপিআইতে পারফরম্যান্স স্ব-ধারাবাহিকতার নীতির একটি আকর্ষণীয় লঙ্ঘন (এই নীতিটি "স্ব-ধারাবাহিক এমপিআই পারফরম্যান্স গাইডলাইনগুলিতে" আরও বিশদে বর্ণিত হয়েছে )।
স্ক্যাটারের নির্দিষ্ট ক্ষেত্রে + অ্যালগ্রেডের তুলনায় জড়ো হওয়া, বিবেচনা করুন যে পূর্ববর্তী সময়ে, সমস্ত ডেটা অবশ্যই একটি একক প্রক্রিয়াতে আসা এবং যাওয়া উচিত, এটি এটিকে বাধা তৈরি করে, যেখানে অ্যালগাদারে, তাত্ক্ষণিকভাবে সমস্ত স্তরের মধ্যে এবং বাইরে প্রবাহিত হতে পারে , কারণ সমস্ত র্যাঙ্কের কাছে অন্য সমস্ত র্যাঙ্কে প্রেরণের জন্য কিছু ডেটা থাকে। তবে, সমস্ত নোড থেকে একবারে ডেটা প্রেরণ করা কিছু নেটওয়ার্কে অগত্যা ভাল ধারণা নয়।
অবশেষে, এই প্রশ্নের উত্তর দেওয়ার সর্বোত্তম উপায় হ'ল আপনার কোডে নিম্নলিখিতটি করা এবং পরীক্ষার মাধ্যমে প্রশ্নের উত্তর দেওয়া।
#ifdef TWO_MPI_CALLS_ARE_BETTER_THAN_ONE
MPI_Scatter(..)
MPI_Gather(..)
#else
MPI_Allgather(..)
#endif
এর চেয়েও ভাল বিকল্প হ'ল আপনার কোডটি প্রথম দুটি পুনরাবৃত্তির সময় এটি পরীক্ষামূলকভাবে পরিমাপ করা হয়, তারপরে বাকী পুনরাবৃত্তির জন্য যেটি দ্রুত হয় তা ব্যবহার করুন:
const int use_allgather = 1;
const int use_scatter_then_gather = 2;
int algorithm = 0;
double t0 = 0.0, t1 = 0.0, dt1 = 0.0, dt2 = 0.0;
while (..)
{
if ( (iteration==0 && algorithm==0) || algorithm==use_scatter_then_gather )
{
t0 = MPI_Wtime();
MPI_Scatter(..);
MPI_Gather(..);
t1 = MPI_Wtime();
dt1 = t1-t0;
}
else if ( (iteration==1 && algorithm==0) || algorithm==use_allgather)
{
t0 = MPI_Wtime();
MPI_Allgather(..);
t1 = MPI_Wtime();
dt2 = t1-t0;
}
if (iteration==1)
{
dt2<dt1 ? algorithm=use_allgather : algorithm=use_scatter_then_gather;
}
}
MPI_Scatter
পরেMPI_Gather
এর মত একই যোগাযোগের অর্থ প্রদান করা হয় নাMPI_Allgather
। আপনি উভয় উপায়ে অপারেশন প্রকাশ করার সময় সম্ভবত বাড়াবাড়ি জড়িত?