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

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ในโปรไฟล์ด้านบนซึ่งใช้ Worker ของ Javac 8 ราย เราเห็น Worker ของ Javac หลายราย แพ้การแข่งขันและทำงานเสร็จในasync-worker-finish เธรด ซึ่งเกิดจาก Mnemonic ที่ไม่ใช่ Worker ใช้ทรัพยากรมากพอที่จะ ทำให้ Worker ทำงานช้าลง

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

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

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

ประสิทธิภาพ

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

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

--experimental_dynamic_local_load_factor เป็นตัวเลือกการจัดการทรัพยากรขั้นสูงเวอร์ชันทดลอง โดยมีค่าตั้งแต่ 0 ถึง 1 และค่า 0 จะเป็นการปิดฟีเจอร์นี้ เมื่อตั้งค่าเป็นค่าที่สูงกว่า 0 Bazel จะปรับจำนวนการดำเนินการที่กำหนดเวลาไว้ในเครื่องเมื่อมีการดำเนินการจำนวนมากที่รอการกำหนดเวลา การตั้งค่าเป็น 1 จะช่วยให้กำหนดเวลาการดำเนินการได้มากเท่าที่ CPU พร้อมใช้งาน (ตาม --local_cpu_resources) ส่วนค่าที่ต่ำกว่าจะกำหนดจำนวนการดำเนินการที่กำหนดเวลาไว้ให้ลดลงตามนั้นเมื่อมีการดำเนินการจำนวนมากขึ้นที่พร้อมใช้งาน แม้จะฟังดูขัดกับสัญชาตญาณ แต่หากมีระบบระยะไกลที่ดี การดำเนินการในเครื่องก็ไม่ได้ช่วยอะไรมากนักเมื่อมีการดำเนินการหลายอย่าง และควรใช้ CPU ในเครื่องเพื่อจัดการการดำเนินการระยะไกลจะดีกว่า

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

--experimental_dynamic_ignore_local_signals สามารถใช้เพื่ออนุญาตให้สาขาที่อยู่ห่างไกล เข้าควบคุมเมื่อการแยกกระบวนการในเครื่องสิ้นสุดลงเนื่องจากสัญญาณที่กำหนด ซึ่งมีประโยชน์อย่างยิ่งเมื่อใช้ร่วมกับขีดจำกัดทรัพยากรของ Worker (ดู--experimental_worker_memory_limit_mb, --experimental_worker_sandbox_hardening และ --experimental_sandbox_memory_limit_mb) ซึ่งกระบวนการของ Worker อาจถูกปิดเมื่อใช้ทรัพยากรมากเกินไป

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

การแก้ปัญหา

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

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