การดำเนินการแบบไดนามิก

รายงานปัญหา ดูแหล่งที่มา

การดำเนินการแบบไดนามิกเป็นฟีเจอร์ใน Bazel ตั้งแต่เวอร์ชัน 0.21 โดยเริ่มดำเนินการแบบเดียวกันทั้งในเครื่องและระยะไกลพร้อมกันโดยใช้เอาต์พุตจาก Branch แรกที่เสร็จสมบูรณ์ ซึ่งเป็นการยกเลิกสาขาอื่น ซึ่งรวมพลังการดำเนินการและ/หรือแคชขนาดใหญ่ที่ใช้ร่วมกันของระบบบิลด์ระยะไกลที่มีเวลาในการตอบสนองต่ำของการดำเนินการภายในเครื่อง ซึ่งให้ผลลัพธ์ที่ดีที่สุดทั้ง 2 อย่างในการสร้างบิลด์ที่ปลอดภัยและเพิ่มขึ้น

หน้านี้จะอธิบายวิธีเปิดใช้ ปรับแต่ง และแก้ไขข้อบกพร่องของการดำเนินการแบบไดนามิก หากคุณตั้งค่าการดำเนินการทั้งในเครื่องและระยะไกลไว้และพยายามปรับการตั้งค่า Bazel เพื่อประสิทธิภาพที่ดีขึ้น หน้านี้มีไว้สำหรับคุณ หากยังไม่ได้ตั้งค่าการดำเนินการระยะไกล ให้ไปที่ภาพรวมการดำเนินการระยะไกลของ Bazel ก่อน

เปิดใช้การดำเนินการแบบไดนามิกไหม

โมดูลการดำเนินการแบบไดนามิกเป็นส่วนหนึ่งของ Bazel แต่การจะใช้ประโยชน์จากการดำเนินการแบบไดนามิก คุณจะต้องคอมไพล์ได้ทั้งในเครื่องและระยะไกลจากการตั้งค่า Bazel เดียวกันอยู่แล้ว

หากต้องการเปิดใช้โมดูลการดำเนินการแบบไดนามิก ให้ส่งแฟล็ก --internal_spawn_scheduler ไปยัง Bazel การดำเนินการนี้จะเพิ่มกลยุทธ์การดำเนินการใหม่ที่ชื่อว่า dynamic ตอนนี้คุณสามารถใช้กลยุทธ์นี้เป็นกลยุทธ์สําหรับการจำที่ต้องการเรียกใช้แบบไดนามิก เช่น --strategy=Javac=dynamic ได้แล้ว โปรดดูหัวข้อถัดไปเพื่อดูวิธีเลือกความทรงจำที่จะเปิดใช้การดำเนินการแบบไดนามิก

สำหรับเทคนิคการจำที่ใช้กลยุทธ์แบบไดนามิก กลยุทธ์การดำเนินการจากระยะไกลจะนำมาจาก Flag --dynamic_remote_strategy และกลยุทธ์ในพื้นที่จาก Flag --dynamic_local_strategy การส่ง --dynamic_local_strategy=worker,sandboxed จะตั้งค่าเริ่มต้นสำหรับสาขาของการดำเนินการแบบไดนามิกในเครื่องเพื่อลองด้วยผู้ปฏิบัติงานหรือการดำเนินการที่ใช้แซนด์บ็อกซ์ตามลำดับดังกล่าว การส่ง --dynamic_local_strategy=Javac=worker จะลบล้างค่าเริ่มต้นสำหรับช่วยจำ Javac เท่านั้น เวอร์ชันรีโมตทำงานในลักษณะเดียวกัน คุณระบุแฟล็กทั้ง 2 รายการได้หลายครั้ง หากดำเนินการในเครื่องไม่ได้ ระบบจะเรียกใช้การดำเนินการดังกล่าวจากระยะไกลตามปกติ และในทางกลับกันด้วย

หากระบบระยะไกลมีแคช ธง --local_execution_delay จะเพิ่มการหน่วงเวลาเป็นมิลลิวินาทีในการเรียกใช้ภายในหลังจากที่ระบบระยะไกลระบุว่าพบแคช ซึ่งจะหลีกเลี่ยงการเรียกใช้การดำเนินการในเครื่องเมื่อมีแนวโน้มที่จะเกิดแคช Hit มากขึ้น ค่าเริ่มต้นคือ 1, 000 มิลลิวินาที แต่ควรปรับแต่งให้นานกว่าการเข้าชมแคชตามปกติเล็กน้อย เวลาจริงจะขึ้นอยู่กับระบบระยะไกลและระยะเวลาที่ใช้เดินทางไป-กลับ โดยปกติแล้ว ค่าสำหรับผู้ใช้ทุกคนในระบบระยะไกลหนึ่งๆ จะเหมือนกัน เว้นแต่ว่าผู้ใช้บางส่วนจะอยู่ไกลพอที่จะเพิ่มเวลาในการตอบสนองไป-กลับ คุณสามารถใช้ฟีเจอร์การทำโปรไฟล์ Bazel เพื่อดูว่า Hit แคชโดยทั่วไปใช้เวลานานแค่ไหน

การดำเนินการแบบไดนามิกใช้ได้กับกลยุทธ์แซนด์บ็อกซ์ในเครื่องและผู้ปฏิบัติงานถาวร ผู้ปฏิบัติงานถาวรจะทำงานกับแซนด์บ็อกซ์โดยอัตโนมัติเมื่อใช้กับการดำเนินการแบบไดนามิก และจะใช้ผู้ปฏิบัติงานมัลติเพล็กซ์ไม่ได้ ในระบบของ Darwin และ Windows กลยุทธ์แซนด์บ็อกซ์อาจทำได้ช้า คุณสามารถส่ง --reuse_sandbox_directories เพื่อลดค่าใช้จ่ายในการสร้างแซนด์บ็อกซ์ในระบบเหล่านี้

การดำเนินการแบบไดนามิกยังทํางานด้วยกลยุทธ์ standalone ได้ด้วย แต่เนื่องจากกลยุทธ์ standalone ต้องล็อกเอาต์พุตเมื่อเริ่มดําเนินการ จึงบล็อกกลยุทธ์ระยะไกลไม่ให้เสร็จสิ้นก่อนได้อย่างมีประสิทธิภาพ แฟล็ก --experimental_local_lockfree_output ช่วยให้แก้ปัญหานี้ได้โดยอนุญาตให้การดำเนินการในเครื่องเขียนไปยังเอาต์พุตโดยตรง แต่ล้มเลิกการดำเนินการระยะไกลหากการดำเนินการดังกล่าวเสร็จสิ้นก่อน

หากสาขาหนึ่งของการดำเนินการแบบไดนามิกเสร็จสิ้นก่อนแต่ดำเนินการไม่สำเร็จ การดำเนินการทั้งหมดจะล้มเหลว นี่เป็นทางเลือกที่ตั้งใจเพื่อป้องกันการสังเกตความแตกต่างระหว่างการดำเนินการในเครื่องและจากระยะไกล

สำหรับข้อมูลพื้นฐานเพิ่มเติมเกี่ยวกับวิธีการทำงานของการดำเนินการแบบไดนามิกและการล็อก โปรดดูบล็อกโพสต์ที่ยอดเยี่ยมของ JulioMerino

ฉันควรใช้การดำเนินการแบบไดนามิกเมื่อใด

การดำเนินการแบบไดนามิกต้องใช้ระบบการดำเนินการระยะไกลบางรูปแบบ ปัจจุบันยังไม่สามารถใช้ระบบระยะไกลที่ใช้แคชเท่านั้นได้ เนื่องจากการไม่พบแคชจะถือว่าเป็นการดำเนินการที่ล้มเหลว

การดำเนินการบางประเภทไม่เหมาะกับการดำเนินการจากระยะไกล ตัวเลือกที่ดีที่สุดคือทรัพยากรที่ทำงานเร็วกว่าภายในเครื่องอยู่แล้ว เช่น ผ่านการใช้ผู้ปฏิบัติงานถาวร หรือผู้ที่ทำงานเร็วพอที่จะทำให้โอเวอร์เฮดของการดำเนินการระยะไกลใช้เวลาดำเนินการ เนื่องจากการดำเนินการเฉพาะเครื่องจะล็อกทรัพยากรของ CPU และหน่วยความจำจำนวนหนึ่ง การดำเนินการที่ไม่อยู่ในหมวดหมู่เหล่านั้นจึงเป็นเพียงการหน่วงเวลาการดำเนินการสำหรับการดำเนินการดังกล่าวเท่านั้น

ตั้งแต่รุ่น 5.0.0-pre.20210708.4 การทำโปรไฟล์ประสิทธิภาพมีข้อมูลเกี่ยวกับการทำงานของผู้ปฏิบัติงาน รวมถึงเวลาที่ใช้ในการดำเนินการตามคำของานหลังจากที่แพ้การแข่งขันด้านปฏิบัติการแบบไดนามิก หากเห็นว่าเทรดผู้ปฏิบัติงานที่ดำเนินการแบบไดนามิกใช้เวลาอย่างมากในการรับทรัพยากรหรือใช้เวลานานใน async-worker-finish แสดงว่าอาจมีการดำเนินการในพื้นที่ที่ช้าซึ่งทําให้ชุดข้อความของผู้ปฏิบัติงานล่าช้า

การทำโปรไฟล์ข้อมูลมีประสิทธิภาพการดำเนินการแบบไดนามิกไม่ดี

ในโปรไฟล์ด้านบนซึ่งใช้ผู้ปฏิบัติงาน Javac 8 คน เราพบว่าผู้ปฏิบัติงาน Javac จำนวนมากแพ้การแข่งขันและทำงานในชุด async-worker-finish จนเสร็จ ปัญหานี้เกิดจากการที่ผู้ปฏิบัติงานจำไม่ได้ต้องใช้ทรัพยากรมากพอในการหน่วงเวลาผู้ปฏิบัติงาน

ทำโปรไฟล์ข้อมูลด้วยประสิทธิภาพการดำเนินการแบบไดนามิกที่ดียิ่งขึ้น

เมื่อ Javac เพียงอย่างเดียวที่เรียกใช้ด้วยการดำเนินการแบบไดนามิก มีเพียงประมาณครึ่งหนึ่งของผู้ปฏิบัติงานที่เริ่มแล้วเท่านั้นที่จะแพ้การแข่งขันหลังจากเริ่มทำงาน

เลิกใช้งานแฟล็ก --experimental_spawn_scheduler ที่แนะนำก่อนหน้านี้แล้ว โดยจะเปิดการดำเนินการแบบไดนามิกและกำหนดให้ dynamic เป็นกลยุทธ์เริ่มต้นสำหรับการช่วยจำทั้งหมด ซึ่งมักจะทำให้เกิดปัญหาประเภทนี้

การแก้ปัญหา

ปัญหาเกี่ยวกับการดำเนินการแบบไดนามิกนั้นอาจเป็นปัญหาเล็กๆ น้อยๆ และแก้ไขข้อบกพร่องได้ยาก เนื่องจากปัญหาเหล่านี้จะเกิดขึ้นได้เฉพาะเมื่อใช้การดำเนินการภายในเครื่องร่วมกับการดำเนินการระยะไกลบางรายการเท่านั้น --debug_spawn_scheduler จะเพิ่มเอาต์พุตเพิ่มเติมจากระบบดำเนินการแบบไดนามิกที่ช่วยแก้ไขข้อบกพร่องของปัญหาเหล่านี้ได้ คุณยังปรับแฟล็ก --local_execution_delay และจำนวนงานระยะไกลกับงานในเครื่องได้ด้วย เพื่อให้ทำให้เกิดปัญหาซ้ำได้ง่ายขึ้น

หากพบปัญหาเกี่ยวกับการดำเนินการแบบไดนามิกโดยใช้กลยุทธ์ standalone ให้ลองเรียกใช้โดยไม่ใช้ --experimental_local_lockfree_output หรือเรียกใช้การกระทำเกี่ยวกับสถานที่โดยใช้แซนด์บ็อกซ์ ซึ่งอาจทำให้การสร้างของคุณช้าลงเล็กน้อย (ดูด้านบนหากคุณใช้ Mac หรือ Windows) แต่จะนำสาเหตุบางประการที่อาจทำให้ดำเนินการไม่สำเร็จออก