รายการของฉันไม่มีลำดับที่เฉพาะเจาะจง อินเทอร์เฟซควร:
- เป็นส่วนหัวเท่านั้นโดยไม่มีการอ้างอิงใด ๆ แต่
<mpi.h>
และไลบรารีมาตรฐาน
- ทั่วไปและขยายออกได้
- ไม่ใช่การปิดกั้นเท่านั้น (หากคุณต้องการบล็อกจากนั้นบล็อกอย่างชัดเจนไม่ใช่ค่าเริ่มต้น)
- อนุญาตการโยงแบบต่อเนื่องของการดำเนินการที่ไม่ปิดกั้น
- รองรับการขยายและการจัดลำดับอย่างมีประสิทธิภาพ (Boost.Fusion เช่นนั้นใช้งานได้กับ RMA)
- มีโทษเป็นนามธรรมอย่างน้อย (กล่าวคืออย่างน้อยก็เร็วเท่าอินเตอร์เฟส C)
- ปลอดภัย (ผู้ทำลายอนาคตที่ไม่พร้อมเรียกว่า? -> std :: ยุติ!),
- มี
DEBUG
โหมดที่แข็งแกร่งด้วยการยืนยันมากมาย
- พิมพ์ปลอดภัยมาก (ไม่มี ints / void * สำหรับทุกอย่าง heck ฉันต้องการแท็กเป็นแบบ!),
- มันควรทำงานกับ lambdas (เช่นลด + lambda)
- ใช้ข้อยกเว้นอย่างสม่ำเสมอเป็นกลไกการรายงานข้อผิดพลาดและการจัดการข้อผิดพลาด (ไม่มีรหัสข้อผิดพลาดอีกต่อไป!
- MPI-IO ควรนำเสนออินเตอร์เฟส I / O ที่ไม่มีการบล็อกในรูปแบบของ Boost.AFIO
- และปฏิบัติตามแนวทางการออกแบบอินเตอร์เฟส C ++ ที่ทันสมัย (กำหนดประเภททั่วไปฟังก์ชั่นที่ไม่เป็นสมาชิกที่ไม่ใช่สมาชิกเล่นได้ดีกับซีแมนทิกส์ย้ายการดำเนินการช่วงที่รองรับ ... )
พิเศษ:
อนุญาตให้ฉันเลือกผู้ดำเนินการของสภาพแวดล้อม MPI นั่นคือเธรดพูลที่ใช้ ตอนนี้คุณสามารถมีแอปพลิเคชันที่มี OpenMP, MPI, CUDA และ TBB ... ทั้งหมดในเวลาเดียวกันโดยที่แต่ละ run-time คิดว่ามันเป็นเจ้าของสภาพแวดล้อมและขอให้ระบบปฏิบัติการใช้เธรดทุกครั้งที่รู้สึก มัน. อย่างจริงจัง?
ใช้หลักการตั้งชื่อ STL (และ Boost) ทำไม? โปรแกรมเมอร์ C ++ ทุกคนรู้ดี
ฉันต้องการเขียนโค้ดเช่นนี้:
auto buffer = some_t{no_ranks};
auto future = gather(comm, root(comm), my_offsets, buffer)
.then([&](){
/* when the gather is finished, this lambda will
execute at the root node, and perform an expensive operation
there asynchronously (compute data required for load
redistribution) whose result is broadcasted to the rest
of the communicator */
return broadcast(comm, root(comm), buffer);
}).then([&]() {
/* when broadcast is finished, this lambda executes
on all processes in the communicator, performing an expensive
operation asynchronously (redistribute the load,
maybe using non-blocking point-to-point communication) */
return do_something_with(buffer);
}).then([&](auto result) {
/* finally perform a reduction on the result to check
everything went fine */
return all_reduce(comm, root(comm), result,
[](auto acc, auto v) { return acc && v; });
}).then([&](auto result) {
/* check the result at every process */
if (result) { return; /* we are done */ }
else {
root_only([](){ write_some_error_log(); });
throw some_exception;
}
});
/* Here nothing has happened yet! */
/* ... lots and lots of unrelated code that can execute concurrently
and overlaps with communication ... */
/* When we now call future.get() we will block
on the whole chain (which might have finished by then!).
*/
future.get();
ลองคิดดูว่าเราจะเชื่อมโยงการปฏิบัติการทั้งหมดนี้โดยใช้ MPI_C request
ได้อย่างไร คุณจะต้องทดสอบในหลาย ๆ ขั้นตอน (หรือทุก ๆ ครั้ง) ผ่านรหัสที่ไม่เกี่ยวข้องทั้งหมดจำนวนมากเพื่อดูว่าคุณสามารถเลื่อนสายของคุณโดยไม่ปิดกั้นหรือไม่