ค่าใช้จ่ายในการเปลี่ยนสถานะคืออะไร?


25

โปรแกรมเมอร์ควรมีความคิดที่ดีเกี่ยวกับค่าใช้จ่ายของการดำเนินการบางอย่างเช่นค่าใช้จ่ายในการเรียนการสอนบน CPU, ค่าใช้จ่ายของ L1, L2, หรือ L3 Cache, ค่า LHS

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

  1. การเปลี่ยนเครื่องแบบของ Shader
  2. การเปลี่ยนแปลงบัฟเฟอร์จุดสุดยอดที่ใช้งานอยู่
  3. การเปลี่ยนแปลงหน่วยพื้นผิวที่ใช้งานอยู่
  4. การเปลี่ยนแปลงโปรแกรม shader ที่ใช้งานอยู่
  5. การเปลี่ยนบัฟเฟอร์เฟรมที่แอ็คทีฟ

แต่นั่นเป็นกฎง่ายๆที่อาจจะไม่ถูกต้องและฉันก็ไม่รู้ว่าคำสั่งของขนาดนั้นคืออะไร หากเราพยายามใส่หน่วย, ns, รอบสัญญาณนาฬิกาหรือจำนวนคำสั่งเราพูดถึงเท่าไหร่?

คำตอบ:


26

ข้อมูลส่วนใหญ่ที่ฉันเห็นคือค่าใช้จ่ายสัมพัทธ์ของการเปลี่ยนแปลงสถานะต่าง ๆ มาจาก Cass Everitt และคำพูดของ John McDonald เกี่ยวกับการลดค่าใช้จ่าย OpenGL APIตั้งแต่เดือนมกราคม 2014 การพูดคุยของพวกเขารวมสไลด์นี้ (ที่ 31:55):

ต้นทุนสัมพัทธ์ของการเปลี่ยนแปลงสถานะ

การพูดคุยไม่ได้ให้ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการวัด (หรือแม้กระทั่งว่าพวกเขากำลังวัดค่า CPU หรือ GPU หรือทั้งสองอย่าง!) แต่อย่างน้อยมันก็เข้ากันได้กับภูมิปัญญาดั้งเดิม: เปลี่ยนเป้าหมายและเปลี่ยนโปรแกรม shader เป็นค่าใช้จ่ายที่แพงที่สุดและอัพเดทอย่างน้อยที่สุดโดยมีจุดสุดยอดบัฟเฟอร์และการเปลี่ยนแปลงพื้นผิวอยู่ตรงกลาง การพูดคุยที่เหลือของพวกเขายังมีภูมิปัญญาที่น่าสนใจมากมายเกี่ยวกับการลดค่าใช้จ่ายในการเปลี่ยนแปลงสถานะ


2
ฉันกำลังเลือกคำตอบนี้เนื่องจากมันให้ลำดับความสำคัญซึ่งใกล้เคียงกับที่ฉันถามมากที่สุดถึงแม้ว่าแหล่งข้อมูลที่กล่าวมาจะไม่ได้ให้คำอธิบายมากนัก
Julien Guertault

27

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

ก่อนการเปลี่ยนแปลงทุกสถานะอาจมีทั้งต้นทุนด้าน CPU และต้นทุนด้าน GPU ค่าใช้จ่าย CPU อาจขึ้นอยู่กับไดรเวอร์และกราฟิค API ของคุณซึ่งจ่ายให้กับเธรดหลักหรือบางส่วนบนเธรดพื้นหลัง

ประการที่สองค่าใช้จ่าย GPU อาจขึ้นอยู่กับปริมาณงานในเที่ยวบิน GPU ที่ทันสมัยนั้นมีท่อส่งก๊าซมากและชอบที่จะได้รับงานจำนวนมากในการบินในครั้งเดียวและการชะลอตัวที่ใหญ่ที่สุดที่คุณสามารถทำได้คือจากการปิดกั้นท่อส่งเพื่อให้ทุกอย่างที่อยู่ในเที่ยวบินในปัจจุบันจะต้องออกจากตำแหน่ง สิ่งที่สามารถทำให้แผงขายท่อส่งก๊าซ? ขึ้นอยู่กับ GPU ของคุณ!

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

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

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

ส่วนใหญ่ของต้นทุนสำหรับการเปลี่ยนแปลงสถานะสำหรับทรัพยากร shader คือด้าน CPU เมื่อใดก็ตามที่คุณตั้งค่าบัฟเฟอร์คงที่ใหม่ไดรเวอร์มักจะคัดลอกเนื้อหาของบัฟเฟอร์คงที่นั้นลงในสตรีมคำสั่งสำหรับ GPU หากคุณตั้งค่าชุดเดียวคนขับมีแนวโน้มที่จะเปลี่ยนเป็นบัฟเฟอร์คงที่ขนาดใหญ่ด้านหลังของคุณดังนั้นจึงต้องค้นหาออฟเซ็ตสำหรับชุดนั้นในบัฟเฟอร์คงที่คัดลอกค่าในจากนั้นทำเครื่องหมายบัฟเฟอร์คงที่ สกปรกเพื่อให้สามารถคัดลอกลงในสตรีมคำสั่งก่อนที่จะดึงการโทรครั้งต่อไป หากคุณผูกพื้นผิวหรือบัฟเฟอร์จุดสุดยอดใหม่ไดรเวอร์อาจจะคัดลอกโครงสร้างการควบคุมสำหรับทรัพยากรรอบ ๆ นอกจากนี้หากคุณใช้ GPU แยกบนระบบมัลติทาสก์คนขับจำเป็นต้องติดตามทุกทรัพยากรที่คุณใช้และเมื่อคุณเริ่มใช้มันเพื่อให้เคอร์เนล ' ผู้จัดการหน่วยความจำของ GPU สามารถรับประกันได้ว่าหน่วยความจำสำหรับทรัพยากรนั้นจะอยู่ใน VRAM ของ GPU เมื่อมีการวาด หลักการ:การเปลี่ยนแปลงสถานะทำให้คนขับสลับหน่วยความจำไปรอบ ๆ เพื่อสร้างสตรีมคำสั่งขั้นต่ำสำหรับ GPU

เมื่อคุณเปลี่ยน shader ปัจจุบันคุณอาจทำให้แคชของ GPU พลาด (มีแคชคำสั่งด้วย!) โดยหลักการแล้วงานของ CPU ควรถูก จำกัด ให้ใส่คำสั่งใหม่ในสตรีมคำสั่งที่ระบุว่า "ใช้ shader" แม้ว่าในความเป็นจริงแล้วจะมีการรวบรวม shader ทั้งหมดเพื่อจัดการกับ ไดรเวอร์ GPU มักจะรวมตัวกันอย่างเชื่องช้าแม้ว่าคุณจะสร้าง shader ล่วงหน้า มีความเกี่ยวข้องกับหัวข้อนี้มากขึ้น แต่บางรัฐไม่ได้รับการสนับสนุนโดยฮาร์ดแวร์ GPU และรวบรวมไว้ในโปรแกรม shader แทน ตัวอย่างหนึ่งที่ได้รับความนิยมคือรูปแบบจุดสุดยอด: สิ่งเหล่านี้อาจถูกรวบรวมไว้ในตัวแบ่งจุดยอดแทนที่จะแยกรัฐบนชิป ดังนั้นหากคุณใช้รูปแบบจุดสุดยอดที่คุณไม่ได้ใช้กับจุดสุดยอดเฉพาะก่อน ตอนนี้คุณอาจต้องจ่ายค่าใช้จ่าย CPU จำนวนมากเพื่อแก้ไข shader และคัดลอกโปรแกรม shader ไปยัง GPU นอกจากนี้คอมไพเลอร์ไดรเวอร์และ shader อาจสมรู้ร่วมคิดในการทำสิ่งต่าง ๆ เพื่อเพิ่มประสิทธิภาพการทำงานของโปรแกรม shader นี่อาจหมายถึงการปรับโครงสร้างหน่วยความจำให้เหมาะสมที่สุดของคุณและโครงสร้างการควบคุมทรัพยากรเพื่อให้พวกเขาได้รับการบรรจุไว้ในหน่วยความจำหรือ shader ที่อยู่ติดกัน ดังนั้นเมื่อคุณเปลี่ยนเฉดสีมันอาจทำให้คนขับดูทุกสิ่งที่คุณผูกไว้กับไปป์ไลน์แล้วบรรจุในรูปแบบที่แตกต่างไปจากเดิมอย่างสิ้นเชิงสำหรับ shader ใหม่แล้วคัดลอกลงในสตรีมคำสั่ง หลักการ: นี่อาจหมายถึงการปรับโครงสร้างหน่วยความจำให้เหมาะสมที่สุดของคุณและโครงสร้างการควบคุมทรัพยากรเพื่อให้พวกเขาได้รับการบรรจุไว้ในหน่วยความจำหรือ shader ที่อยู่ติดกัน ดังนั้นเมื่อคุณเปลี่ยนเฉดสีมันอาจทำให้คนขับดูทุกสิ่งที่คุณผูกไว้กับไปป์ไลน์แล้วบรรจุในรูปแบบที่แตกต่างไปจากเดิมอย่างสิ้นเชิงสำหรับ shader ใหม่แล้วคัดลอกลงในสตรีมคำสั่ง หลักการ: นี่อาจหมายถึงการปรับโครงสร้างหน่วยความจำให้เหมาะสมที่สุดของคุณและโครงสร้างการควบคุมทรัพยากรเพื่อให้พวกเขาได้รับการบรรจุไว้ในหน่วยความจำหรือ shader ที่อยู่ติดกัน ดังนั้นเมื่อคุณเปลี่ยนเฉดสีมันอาจทำให้คนขับดูทุกสิ่งที่คุณผูกไว้กับไปป์ไลน์แล้วบรรจุในรูปแบบที่แตกต่างไปจากเดิมอย่างสิ้นเชิงสำหรับ shader ใหม่แล้วคัดลอกลงในสตรีมคำสั่ง หลักการ:การเปลี่ยนเครื่องเปลี่ยนอาจทำให้เกิดการสับหน่วยความจำ CPU จำนวนมาก

การเปลี่ยนเฟรมบัฟเฟอร์อาจขึ้นอยู่กับการนำไปใช้งานส่วนใหญ่ แต่โดยทั่วไปราคาค่อนข้างแพงใน GPU GPU ของคุณอาจไม่สามารถจัดการการดึงการโทรหลายครั้งไปยังเป้าหมายการแสดงผลที่แตกต่างกันในเวลาเดียวกันดังนั้นจึงอาจต้องหยุดการส่งสัญญาณระหว่างการจับคู่ทั้งสอง อาจต้องล้างแคชเพื่อให้เป้าหมายการเรนเดอร์สามารถอ่านได้ในภายหลัง อาจต้องแก้ไขงานที่เลื่อนออกไปในระหว่างการวาด (เป็นเรื่องธรรมดามากที่จะรวบรวมโครงสร้างข้อมูลแยกต่างหากพร้อมกับบัฟเฟอร์ความลึก, เป้าหมายการแสดงผล MSAA และอื่น ๆ สิ่งนี้อาจจำเป็นต้องได้รับการสรุปเมื่อคุณสลับไปจากเป้าหมายการแสดงผลนั้นหากคุณใช้ GPU ที่เป็นแบบเรียงต่อกัน เช่นเดียวกับ GPU บนมือถือจำนวนมากงานเงาที่เกิดขึ้นจริงจำนวนมากอาจจำเป็นต้องถูกลบทิ้งเมื่อคุณเปลี่ยนจากเฟรมบัฟเฟอร์) หลักการ:การเปลี่ยนเป้าหมายเรนเดอร์มีราคาแพงบน GPU

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.