ค่าใช้จ่ายจริงของการเปลี่ยนแปลงสถานะใด ๆ นั้นแตกต่างกันไปตามปัจจัยหลายอย่างที่คำตอบทั่วไปไม่สามารถทำได้
ก่อนการเปลี่ยนแปลงทุกสถานะอาจมีทั้งต้นทุนด้าน 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 กราฟิกที่คุณชื่นชอบ