สองตัวนี้ต่างกันอย่างไร?
[A]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
สองตัวนี้ต่างกันอย่างไร?
[A]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
คำตอบ:
ฉันไม่คิดว่ามีความแตกต่างอันหนึ่งเป็นทางลัดสำหรับอีกทางหนึ่ง แม้ว่าการใช้งานที่แน่นอนของคุณอาจจัดการกับสิ่งเหล่านี้แตกต่างกัน
โครงสร้างการแชร์แบบขนานรวมกันเป็นทางลัดสำหรับการระบุโครงสร้างแบบขนานที่มีโครงสร้างการแชร์งานเดียวและไม่มีคำสั่งอื่น ๆ อนุประโยคที่ได้รับอนุญาตคือการรวมกันของอนุประโยคที่อนุญาตสำหรับการสร้างแบบขนานและการแชร์เวิร์คแชร์
นำมาจากhttp://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf
ข้อกำหนดสำหรับ OpenMP อยู่ที่นี่:
สิ่งเหล่านี้เทียบเท่า
#pragma omp parallel
สร้างกลุ่มของเธรดในขณะที่#pragma omp for
แบ่งการวนซ้ำแบบวนซ้ำระหว่างเธรดที่เกิด คุณสามารถทำทั้งสองอย่างพร้อมกันได้ด้วย#pragma omp parallel for
คำสั่งผสม
#pragma omp parallel for
คำสั่ง ควรจะมีความแตกต่างบ้าง
นี่คือตัวอย่างของการใช้แยกออกจากกันparallel
และที่นี่for
ในระยะสั้นสามารถใช้สำหรับการจัดสรรแบบไดนามิกของอาร์เรย์เธรดส่วนตัว OpenMP ก่อนที่จะดำเนินการfor
รอบในหลายเธรด เป็นไปไม่ได้ที่จะทำการเริ่มต้นในparallel for
กรณีเดียวกัน
UPD: ในตัวอย่างคำถามไม่มีความแตกต่างระหว่าง pragma เดียวและสอง pragmas แต่ในทางปฏิบัติคุณสามารถสร้างพฤติกรรมการรับรู้เธรดได้มากขึ้นด้วยการแยกคู่ขนานและสำหรับคำสั่ง บางรหัสเช่น:
#pragma omp parallel
{
double *data = (double*)malloc(...); // this data is thread private
#pragma omp for
for(1...100) // first parallelized cycle
{
}
#pragma omp single
{} // make some single thread processing
#pragma omp for // second parallelized cycle
for(1...100)
{
}
#pragma omp single
{} // make some single thread processing again
free(data); // free thread private data
}
แม้ว่าตัวอย่างเฉพาะทั้งสองเวอร์ชันจะเทียบเท่ากันดังที่ได้กล่าวไปแล้วในคำตอบอื่น ๆ แต่ก็ยังมีความแตกต่างเล็กน้อยระหว่างกัน เวอร์ชันแรกมีอุปสรรคโดยนัยที่ไม่จำเป็นซึ่งพบในตอนท้ายของ "omp for" อุปสรรคโดยนัยอื่น ๆ สามารถพบได้ที่ส่วนท้ายของพื้นที่คู่ขนาน การเพิ่ม "nowait" เป็น "omp for" จะทำให้รหัสทั้งสองเทียบเท่ากันอย่างน้อยก็จากมุมมองของ OpenMP ฉันพูดถึงสิ่งนี้เนื่องจากคอมไพเลอร์ OpenMP สามารถสร้างรหัสที่แตกต่างกันเล็กน้อยสำหรับสองกรณี
ฉันเห็นเวลาทำงานที่แตกต่างกันอย่างสิ้นเชิงเมื่อฉันใช้ for loop ใน g ++ 4.7.0 และใช้
std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;
for (int i = 0; i < 5000000; i++)
{
double r1 = ((double)rand() / double(RAND_MAX)) * 5;
double r2 = ((double)rand() / double(RAND_MAX)) * 5;
x.push_back(r1);
y.push_back(r2);
}
int sz = x.size();
#pragma omp parallel for
for (int i = 0; i< sz; i++)
prod[i] = x[i] * y[i];
รหัสซีเรียล (no openmp
) ทำงานใน 79 ms โค้ด "parallel for" ทำงานใน 29 มิลลิวินาที หากฉันละเว้นfor
และใช้#pragma omp parallel
รันไทม์จะยิงได้ถึง 179ms ซึ่งช้ากว่ารหัสซีเรียล (เครื่องมี hw พร้อมกัน 8)
รหัสเชื่อมโยงไปยัง libgomp
#pragma omp for
จะไม่มีการแชร์ลูปแบบมัลติเธรดเลย แต่นั่นไม่ใช่กรณี OPs ลองอีกครั้งโดยมีตัวเลือกเพิ่มเติม#pragma omp for
ภายใน#pragm omp parallel
และควรทำงานคล้ายกัน (ถ้าไม่เหมือนกัน) เหมือน#pragma omp parallel for
เวอร์ชัน
เห็นได้ชัดว่ามีคำตอบมากมาย แต่คำตอบนี้ตอบได้ดีมาก (พร้อมแหล่งที่มา)
#pragma omp for
มอบหมายเฉพาะบางส่วนของลูปสำหรับเธรดที่แตกต่างกันในทีมปัจจุบัน ทีมคือกลุ่มของเธรดที่เรียกใช้โปรแกรม เมื่อเริ่มโปรแกรมทีมประกอบด้วยสมาชิกคนเดียวเท่านั้น : เธรดหลักที่รันโปรแกรมในการสร้างทีมเธรดใหม่คุณต้องระบุคีย์เวิร์ดคู่ขนาน สามารถระบุได้ในบริบทโดยรอบ:
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
และ:
อะไรคือคู่ขนานสำหรับและทีม
ความแตกต่างระหว่างขนานขนานสำหรับและสำหรับมีดังนี้:
ทีมคือกลุ่มของเธรดที่ดำเนินการในปัจจุบัน ในตอนเริ่มต้นโปรแกรมทีมประกอบด้วยเธรดเดียว โครงสร้างแบบขนานจะแยกเธรดปัจจุบันออกเป็นทีมเธรดใหม่ในช่วงระยะเวลาของบล็อก / คำสั่งถัดไปหลังจากนั้นทีมจะรวมกลับเป็นกลุ่มเดียวกัน สำหรับแบ่งงานของ for-loop ระหว่างเธรดของทีมปัจจุบัน
มันไม่ได้สร้างเธรด แต่จะแบ่งงานระหว่างเธรดของทีมที่ดำเนินการอยู่ในปัจจุบันเท่านั้น ขนานสำหรับคือชวเลขสำหรับสองคำสั่งพร้อมกัน: ขนานและสำหรับ. Parallel สร้างทีมใหม่และสำหรับการแยกทีมนั้นเพื่อจัดการกับส่วนต่างๆของลูป ถ้าโปรแกรมของคุณไม่เคยมีโครงสร้างแบบขนานแสดงว่ามีเธรดไม่เกินหนึ่งเธรด เธรดหลักที่เริ่มต้นโปรแกรมและรันเช่นเดียวกับในโปรแกรมที่ไม่ใช่เธรด
schedule(static, chunk)
clause in สำหรับ directive ฉันพบปัญหา รหัสทำงานได้ดี แต่เมื่อฉันเรียกใช้รหัสนี้จากโปรแกรม MPI มันจะทำงานในวงวนไม่สิ้นสุด ตัวนับลูปเป็นศูนย์ในการวนซ้ำทั้งหมดของลูปนี้ ฉันมีตัวนับลูปที่กำหนดให้เป็นส่วนตัวใน#pragma omp parallel
คำสั่ง ไม่รู้ว่าทำไมมันถึงล้มเหลวเมื่อ MPI เรียกใช้รหัสเท่านั้น ฉันค่อนข้างแน่ใจว่าแต่ละกระบวนการ MPI กำลังทำงานบนโปรเซสเซอร์ที่แตกต่างกันของคลัสเตอร์หากเป็นเช่นนั้น ไม่รู้ว่ากำหนดการทำให้เกิดปัญหาหรือไม่