คำว่า "CPU bound" และ "I / O bound" หมายถึงอะไร
คำว่า "CPU bound" และ "I / O bound" หมายถึงอะไร
คำตอบ:
มันใช้งานง่ายสวย:
โปรแกรมจะทำงานกับ CPU ถ้ามันทำงานได้เร็วขึ้นถ้า CPU นั้นเร็วกว่านั่นคือมันใช้เวลาส่วนใหญ่เพียงแค่ใช้ CPU (ทำการคำนวณ) โปรแกรมที่คำนวณตัวเลขใหม่ของπโดยทั่วไปจะเป็น CPU-bound มันเป็นเพียงตัวเลขที่บดขยี้
โปรแกรมจะถูกผูกไว้กับ I / O ถ้ามันจะไปเร็วขึ้นถ้าระบบย่อยของ I / O เร็วขึ้น ความหมายของระบบ I / O ที่แน่นอนนั้นสามารถเปลี่ยนแปลงได้ ฉันมักจะเชื่อมโยงมันกับดิสก์ แต่แน่นอนว่าเครือข่ายหรือการสื่อสารโดยทั่วไปนั้นเป็นเรื่องปกติเช่นกัน โปรแกรมที่มองผ่านไฟล์ขนาดใหญ่สำหรับข้อมูลบางอย่างอาจกลายเป็น I / O ที่ถูกผูกไว้เนื่องจากคอขวดนั้นคือการอ่านข้อมูลจากดิสก์ (จริง ๆ แล้วตัวอย่างนี้อาจจะล้าสมัยไปแล้วหลายร้อย MB / s เข้ามาจาก SSD)
CPU Boundหมายถึงอัตราที่กระบวนการดำเนินการถูก จำกัด ด้วยความเร็วของ CPU งานที่ดำเนินการคำนวณกับชุดตัวเลขขนาดเล็กเช่นการคูณเมทริกซ์ขนาดเล็กมีแนวโน้มว่าจะถูกผูกไว้กับ CPU
I / O Boundหมายถึงอัตราที่กระบวนการดำเนินการถูก จำกัด ด้วยความเร็วของระบบย่อย I / O งานที่ประมวลผลข้อมูลจากดิสก์ตัวอย่างเช่นการนับจำนวนบรรทัดในไฟล์น่าจะเป็น I / O ที่ถูกผูกไว้
หน่วยความจำที่ถูกผูกไว้หมายถึงอัตราที่กระบวนการดำเนินการถูก จำกัด ด้วยจำนวนหน่วยความจำที่มีอยู่และความเร็วของการเข้าถึงหน่วยความจำนั้น งานที่ประมวลผลข้อมูลหน่วยความจำจำนวนมากตัวอย่างเช่นการคูณเมทริกซ์ขนาดใหญ่น่าจะเป็น Memory Bound
Cache boundหมายถึงอัตราที่กระบวนการดำเนินการถูก จำกัด โดยจำนวนและความเร็วของแคชที่มีอยู่ งานที่ประมวลผลข้อมูลมากกว่าที่พอดีในแคชจะถูกผูกไว้กับแคช
I / O Bound จะช้ากว่า Memory Bound จะช้ากว่า Cache Bound จะช้ากว่า CPU Bound
วิธีแก้ปัญหาการผูก I / O ไม่จำเป็นต้องได้รับหน่วยความจำเพิ่มเติม ในบางสถานการณ์อัลกอริทึมการเข้าถึงสามารถออกแบบรอบ I / O, หน่วยความจำหรือแคช จำกัด ดูแคชลบเลือนอัลกอริทึม
แบบมัลติเธรด
ในคำตอบนี้ฉันจะตรวจสอบกรณีการใช้งานที่สำคัญอย่างหนึ่งของการแยกความแตกต่างระหว่าง CPU กับ IO งานที่มีขอบเขต: เมื่อเขียนโค้ดแบบมัลติเธรด
ตัวอย่างที่ถูกผูกไว้ RAM I / O: ผลรวมของเวกเตอร์
พิจารณาโปรแกรมที่รวมค่าทั้งหมดของเวกเตอร์เดียว:
#define SIZE 1000000000
unsigned int is[SIZE];
unsigned int sum = 0;
size_t i = 0;
for (i = 0; i < SIZE; i++)
/* Each one of those requires a RAM access! */
sum += is[i]
การขนานกันโดยการแบ่งอาร์เรย์ให้เท่ากันสำหรับแต่ละคอร์ของคุณนั้นมีประโยชน์ จำกัด บนเดสก์ท็อปสมัยใหม่ทั่วไป
ตัวอย่างเช่นใน Ubuntu 19.04 ของฉันแล็ปท็อป Lenovo ThinkPad P51 ที่มี CPU: Intel Core i7-7820HQ CPU (4 คอร์ / 8 เธรด), RAM: 2x Samsung M471A2K43BB1-CRC (2x 16GiB) ฉันได้รับผลลัพธ์เช่นนี้:
โปรดทราบว่ามีความแปรปรวนจำนวนมากระหว่างการเรียกใช้อย่างไรก็ตาม แต่ฉันไม่สามารถเพิ่มขนาดอาร์เรย์ได้อีกมากตั้งแต่ฉันอยู่ที่ 8GiB และฉันไม่ได้อยู่ในอารมณ์ของสถิติในการวิ่งหลายครั้งในวันนี้ อย่างไรก็ตามเรื่องนี้ดูเหมือนจะเป็นการเรียกใช้ทั่วไปหลังจากทำการทดสอบด้วยตนเองหลายครั้ง
รหัสมาตรฐาน:
POSIX C pthread
ซอร์สโค้ดที่ใช้ในกราฟ
และนี่คือรุ่น C ++ที่ให้ผลลัพธ์แบบอะนาล็อก
ฉันไม่รู้สถาปัตยกรรมคอมพิวเตอร์เพียงพอที่จะอธิบายรูปร่างของเส้นโค้งได้อย่างสมบูรณ์ แต่มีสิ่งหนึ่งที่ชัดเจน: การคำนวณไม่เร็วขึ้นเท่าที่คาดอย่างไร้สาระ 8 เท่าเนื่องจากฉันใช้เธรดทั้งหมด 8 เธรด! ด้วยเหตุผลบางอย่างเธรด 2 และ 3 เป็นสิ่งที่ดีที่สุดและการเพิ่มมากขึ้นทำให้สิ่งต่าง ๆ ช้าลงมาก
เปรียบเทียบสิ่งนี้กับงานที่เชื่อมโยงกับ CPU ซึ่งจริง ๆ แล้วเร็วขึ้น 8 เท่า: 'ของจริง', 'ผู้ใช้' และ 'sys' หมายถึงอะไรในผลลัพธ์ของเวลา (1)
สาเหตุที่โปรเซสเซอร์ทั้งหมดแชร์หน่วยความจำบัสเดียวที่เชื่อมโยงกับ RAM:
CPU 1 --\ Bus +-----+
CPU 2 ---\__________| RAM |
... ---/ +-----+
CPU N --/
ดังนั้นบัสหน่วยความจำจะกลายเป็นคอขวดอย่างรวดเร็วไม่ใช่ซีพียู
สิ่งนี้เกิดขึ้นเนื่องจากการเพิ่มตัวเลขสองตัวใช้เวลาหนึ่งรอบของ CPU การอ่านหน่วยความจำใช้เวลาประมาณ100 รอบของ CPUในฮาร์ดแวร์ 2016
ดังนั้น CPU ที่ทำงานต่อไบต์ของข้อมูลอินพุตมีขนาดเล็กเกินไปและเราเรียกกระบวนการนี้ว่า IO-bound
วิธีเดียวที่จะเพิ่มความเร็วในการคำนวณว่าต่อไปจะเป็นเพื่อเพิ่มความเร็วในหน่วยความจำของแต่ละบุคคลเข้าถึงกับฮาร์ดแวร์หน่วยความจำใหม่เช่นหน่วยความจำหลายช่องทาง
ยกตัวอย่างเช่นการปรับนาฬิกาซีพียูให้เร็วขึ้นจะไม่เป็นประโยชน์มากนัก
ตัวอย่างอื่น ๆ
การคูณเมทริกซ์นั้นผูกกับ CPU บน RAM และ GPU อินพุตประกอบด้วย:
2 * N**2
ตัวเลข แต่:
N ** 3
การคูณจะเสร็จสิ้นและนั่นก็เพียงพอแล้วสำหรับการขนานที่จะคุ้มค่าสำหรับการปฏิบัติที่มีขนาดใหญ่เอ็น
นี่คือสาเหตุที่ไลบรารีการคูณเมทริกซ์ CPU แบบขนานมีดังต่อไปนี้:
การใช้แคชสร้างความแตกต่างอย่างมากต่อความเร็วของการใช้งาน ดูตัวอย่างนี้สอนตัวอย่างเช่นการเปรียบเทียบ GPU
ดูสิ่งนี้ด้วย:
ระบบเครือข่ายเป็นตัวอย่างที่ผูกไว้กับต้นแบบของ IO
แม้เมื่อเราส่งข้อมูลหนึ่งไบต์ก็ยังใช้เวลานานในการเข้าถึงปลายทาง
การร้องขอเครือข่ายขนาดเล็กแบบขนานเช่นคำขอ HTTP สามารถเพิ่มประสิทธิภาพได้อย่างมาก
หากเครือข่ายเต็มความจุอยู่แล้ว (เช่นการดาวน์โหลดทอเรนท์) การทำคู่ขนานยังสามารถเพิ่มเวลาในการตอบสนอง (เช่นคุณสามารถโหลดเว็บเพจ "ในเวลาเดียวกัน")
การดำเนินการที่เชื่อมโยง CPU Cummy จำลองที่ใช้หมายเลขหนึ่งและบีบอัดมันจำนวนมาก:
การเรียงลำดับดูเหมือนจะเป็น CPU ตามการทดลองต่อไปนี้: C ++ 17 อัลกอริทึมแบบขนานได้ถูกใช้งานแล้วหรือไม่ ซึ่งแสดงการปรับปรุงประสิทธิภาพ 4x สำหรับการเรียงลำดับแบบขนาน แต่ฉันต้องการได้รับการยืนยันทางทฤษฎีมากขึ้นเช่นกัน
วิธีค้นหาว่าคุณมี CPU หรือ IO ผูกไว้
Non-RAM ผูกพัน IO เช่นดิสก์เครือข่าย: แล้วถ้าps aux
theck CPU% / 100 < n threads
ถ้าใช่คุณถูกผูกไว้กับ IO เช่นการบล็อกread
s กำลังรอข้อมูลและตัวกำหนดตารางเวลากำลังข้ามขั้นตอนนั้น จากนั้นใช้เครื่องมือเพิ่มเติมเช่นsudo iotop
ตัดสินใจว่าปัญหาใดของ IO
หรือถ้าการประมวลผลเร็วและคุณกำหนดจำนวนเธรดคุณสามารถดูได้ง่ายจากtime
ประสิทธิภาพนั้นดีขึ้นเมื่อจำนวนเธรดเพิ่มขึ้นสำหรับการทำงานของ CPU: สิ่งที่ 'จริง', 'ผู้ใช้' และ 'sys' หมายถึงอะไร ผลผลิตของเวลา (1)?
RAM-IO bound: ยากที่จะบอกได้เนื่องจาก RAM รอเวลารวมอยู่ในCPU%
การวัดดูเพิ่มเติมที่:
ตัวเลือกบางอย่าง:
GPUs
GPU มีคอขวด IO เมื่อคุณถ่ายโอนข้อมูลอินพุตจาก RAM ปกติที่อ่านได้ของ CPU ไปยัง GPU
ดังนั้น GPU สามารถทำได้ดีกว่า CPU สำหรับแอปพลิเคชันที่เชื่อมโยงกับ CPU เท่านั้น
เมื่อข้อมูลถูกถ่ายโอนไปยัง GPU แล้วมันสามารถทำงานบนไบต์เหล่านั้นเร็วกว่าที่ CPU ทำได้เนื่องจาก GPU:
มีการแปลข้อมูลมากกว่าระบบ CPU ส่วนใหญ่และสามารถเข้าถึงข้อมูลได้เร็วขึ้นสำหรับบางคอร์กว่าบางคอร์
ใช้ประโยชน์จากข้อมูลขนานและเสียสละเวลาแฝงโดยเพียงข้ามข้อมูลใด ๆ ที่ไม่พร้อมใช้งานทันที
เนื่องจาก GPU ต้องทำงานกับข้อมูลอินพุตแบบขนานขนาดใหญ่จึงควรข้ามไปยังข้อมูลถัดไปที่อาจพร้อมใช้งานแทนที่จะรอให้ข้อมูลปัจจุบันพร้อมใช้งานและบล็อกการทำงานอื่น ๆ ทั้งหมดเช่น CPU ทำ
ดังนั้น GPU จะเร็วกว่าซีพียูหากแอปพลิเคชันของคุณ:
ตัวเลือกการออกแบบเหล่านี้มีจุดมุ่งหมายเพื่อการประยุกต์ใช้การเรนเดอร์ 3D ซึ่งมีขั้นตอนหลักดังแสดงในสิ่งที่เป็นเฉดสีใน OpenGL และเราต้องการอะไรบ้าง
ดังนั้นเราจึงสรุปได้ว่าแอปพลิเคชันเหล่านั้นผูกกับ CPU
ด้วยการกำเนิดของ GPGPU ที่ตั้งโปรแกรมได้เราสามารถสังเกตเห็นแอปพลิเคชั่น GPGPU หลายตัวที่ทำหน้าที่เป็นตัวอย่างของการทำงานที่เชื่อมโยงกับ CPU:
การประมวลผลภาพด้วย GLSL เฉดสี?
การประมวลผลภาพในพื้นที่เช่นตัวกรองเบลอนั้นขนานกันอย่างมากในธรรมชาติ
เป็นไปได้หรือไม่ที่จะสร้าง heatmap จากข้อมูลจุดที่ 60 ครั้งต่อวินาที
การพล็อตกราฟกราฟความร้อนหากฟังก์ชันการพล็อตมีความซับซ้อนเพียงพอ
https://www.youtube.com/watch?v=fE0P6H8eK4I "พลวัตของไหลแบบเรียลไทม์: CPU vs GPU" โดยJesúsMartín Berlanga
การแก้สมการเชิงอนุพันธ์ย่อยบางส่วนเช่นสมการเนเวียร์สโตกส์ของพลศาสตร์ของไหล:
ดูสิ่งนี้ด้วย:
CPython Global Intepreter Lock (GIL)
จากกรณีศึกษาอย่างรวดเร็วฉันต้องการชี้ไปที่ Python Global Interpreter Lock (GIL): ล็อก interpreter global (GIL) ใน CPython คืออะไร
รายละเอียดการติดตั้ง CPython นี้จะป้องกันไม่ให้เธรด Python หลายเธรดทำงานอย่างมีประสิทธิภาพโดยใช้งาน CPU-bound เอกสาร CPythonบอกว่า:
รายละเอียดการติดตั้ง CPython: ใน CPython เนื่องจาก Global Interpreter Lock มีเพียงเธรดเดียวเท่านั้นที่สามารถเรียกใช้งานโค้ด Python ได้ในคราวเดียว (แม้ว่าไลบรารี่ที่มุ่งเน้นประสิทธิภาพบางอย่างอาจเอาชนะข้อ จำกัด นี้ได้) หากคุณต้องการใช้งานของคุณที่จะทำให้การใช้งานที่ดีขึ้นของทรัพยากรคอมพิวเตอร์เครื่องแบบ multi-core คุณจะได้รับคำแนะนำในการใช้งานหรือ
multiprocessing
concurrent.futures.ProcessPoolExecutor
อย่างไรก็ตามเธรดยังคงเป็นแบบจำลองที่เหมาะสมหากคุณต้องการรันภารกิจ I / O ที่เชื่อมโยงหลาย ๆ งานพร้อมกัน
ดังนั้นที่นี่เรามีตัวอย่างที่เนื้อหาของ CPU ไม่เหมาะและ I / O ถูก จำกัด
CPU bound หมายถึงโปรแกรมถูกคอขวดโดย CPU หรือหน่วยประมวลผลกลางในขณะที่I / Oถูก จำกัด หมายถึงโปรแกรมนั้นถูกคอขวดโดย I / O หรืออินพุต / เอาท์พุตเช่นการอ่านหรือเขียนลงดิสก์เครือข่ายเป็นต้น
โดยทั่วไปเมื่อทำการปรับโปรแกรมคอมพิวเตอร์ให้ดีที่สุดจะพยายามหาทางแก้ไขปัญหาคอขวดและกำจัดมัน การที่รู้ว่าโปรแกรมของคุณมี CPU ที่ถูกผูกไว้จะช่วยได้ดังนั้นโปรแกรมจึงไม่ได้เพิ่มประสิทธิภาพอย่างอื่นโดยไม่จำเป็น
[และด้วย "คอขวด" ฉันหมายถึงสิ่งที่ทำให้โปรแกรมของคุณช้าลงกว่าที่ควรจะเป็น]
อีกวิธีหนึ่งสำหรับวลีความคิดเดียวกัน:
หากการเร่งความเร็ว CPU ไม่เร่งความเร็วโปรแกรมของคุณอาจเป็นI / O ที่เชื่อมโยง
หากเร่งความเร็ว I / O (เช่นการใช้ดิสก์ที่เร็วกว่า) ก็ไม่ได้ช่วยโปรแกรมของคุณอาจมี CPU ผูกไว้
(ฉันใช้ "อาจเป็น" เพราะคุณต้องคำนึงถึงแหล่งข้อมูลอื่น ๆ หน่วยความจำเป็นตัวอย่างหนึ่ง)
เมื่อโปรแกรมของคุณกำลังรอI / O (เช่นดิสก์อ่าน / เขียนหรืออ่าน / เขียนบนเครือข่าย ฯลฯ ) CPU มีอิสระที่จะทำงานอื่น ๆ แม้ว่าโปรแกรมของคุณจะหยุดทำงาน ความเร็วของโปรแกรมส่วนใหญ่จะขึ้นอยู่กับความเร็วที่ IO สามารถเกิดขึ้นได้และถ้าคุณต้องการเร่งความเร็วคุณจะต้องเร่งความเร็ว I / O
หากโปรแกรมของคุณกำลังรันคำสั่งโปรแกรมจำนวนมากและไม่รอ I / O แสดงว่าเป็น CPU ที่ถูกผูกไว้ การเร่งความเร็ว CPU จะทำให้โปรแกรมทำงานเร็วขึ้น
ไม่ว่าในกรณีใด ๆ กุญแจสำคัญในการเร่งความเร็วของโปรแกรมอาจไม่ใช่เพื่อเพิ่มความเร็วของฮาร์ดแวร์ แต่เพื่อปรับโปรแกรมให้เหมาะสมเพื่อลดปริมาณของ IO หรือ CPU ที่ต้องการหรือเพื่อให้ I / O ทำงานได้ในขณะที่ CPU ทำงานหนัก สิ่ง
I / O ที่ถูกผูกไว้หมายถึงเงื่อนไขที่เวลาที่ใช้ในการคำนวณให้เสร็จสมบูรณ์จะถูกกำหนดโดยหลักโดยระยะเวลาที่ใช้รอการดำเนินการอินพุต / เอาต์พุตที่จะเสร็จสมบูรณ์
นี่เป็นสิ่งที่ตรงกันข้ามกับภารกิจที่ถูกผูกไว้กับ CPU สถานการณ์นี้เกิดขึ้นเมื่ออัตราที่ร้องขอข้อมูลช้ากว่าอัตราที่ใช้หรือในคำอื่น ๆ ใช้เวลาในการขอข้อมูลมากกว่าการประมวลผล
กระบวนการที่ถูกผูกไว้กับ IO: ใช้เวลาในการทำ IO มากกว่าการคำนวณมีซีพียูสั้น ๆ มากมาย กระบวนการที่ถูกผูกไว้กับ CPU: ใช้เวลาในการคำนวณมากขึ้นและมี CPU ที่ยาวมาก ๆ
แกนหลักของการเขียนโปรแกรม async เป็นวัตถุงานและงานซึ่งรูปแบบการดำเนินงานไม่ตรงกัน ได้รับการสนับสนุนโดย async และรอคำสำคัญ ตัวแบบค่อนข้างง่ายในกรณีส่วนใหญ่:
สำหรับรหัส I / O ที่ถูกผูกไว้คุณจะรอการดำเนินการที่ส่งคืนภารกิจหรืองานภายในของวิธีการซิงค์
สำหรับรหัสที่ผูกกับ CPU คุณรอการดำเนินการที่เริ่มต้นบนเธรดพื้นหลังด้วยวิธีการ Task.Run
คำหลักที่รอคอยคือที่ที่เวทมนต์เกิดขึ้น มันให้การควบคุมแก่ผู้เรียกของวิธีการที่ดำเนินการรอและในที่สุดก็ช่วยให้ UI ที่จะตอบสนองหรือบริการที่จะยืดหยุ่น
ตัวอย่าง I / O-Bound: การดาวน์โหลดข้อมูลจากบริการบนเว็บ
private readonly HttpClient _httpClient = new HttpClient();
downloadButton.Clicked += async (o, e) =>
{
// This line will yield control to the UI as the request
// from the web service is happening.
//
// The UI thread is now free to perform other work.
var stringData = await _httpClient.GetStringAsync(URL);
DoSomethingWithData(stringData);
};
ตัวอย่าง CPU-bound: ทำการคำนวณสำหรับเกม
private DamageResult CalculateDamageDone()
{
// Code omitted:
//
// Does an expensive calculation and returns
// the result of that calculation.
}
calculateButton.Clicked += async (o, e) =>
{
// This line will yield control to the UI while CalculateDamageDone()
// performs its work. The UI thread is free to perform other work.
var damageResult = await Task.Run(() => CalculateDamageDone());
DisplayDamage(damageResult);
};
ตัวอย่างด้านบนแสดงวิธีที่คุณสามารถใช้ async และรองาน I / O-bound และ CPU-bound เป็นกุญแจสำคัญที่คุณสามารถระบุได้เมื่องานที่คุณต้องทำคือ I / O-bound หรือ CPU-bound เพราะมันจะส่งผลกระทบอย่างมากต่อประสิทธิภาพการทำงานของรหัสของคุณและอาจนำไปสู่การสร้างโครงสร้างบางอย่างในทางที่ผิด
ต่อไปนี้เป็นคำถามสองข้อที่คุณควรถามก่อนที่คุณจะเขียนโค้ดใด ๆ :
รหัสของคุณจะเป็น "กำลังรอ" บางอย่างเช่นข้อมูลจากฐานข้อมูลหรือไม่
- หากคำตอบของคุณคือ "ใช่" แสดงว่างานของคุณคือ I / O-bound
รหัสของคุณจะทำการคำนวณที่แพงมากหรือไม่
- หากคุณตอบว่า "ใช่" แสดงว่างานของคุณมี CPU-bound
หากงานที่คุณมีคือ I / O ที่ถูกผูกไว้ใช้ async และรอคอยโดยไม่ต้อง Task.Run คุณไม่ควรใช้ Task Parallel Library สาเหตุของเรื่องนี้ได้อธิบายไว้ในบทความAsync in Depth
หากงานที่คุณมีนั้นเชื่อมโยงกับ CPU และคุณใส่ใจกับการตอบสนองให้ใช้ async และรอ แต่จะทำงานออกมาบนเธรดอื่นด้วย Task.Run หากการทำงานเป็นที่เหมาะสมสำหรับการทำงานพร้อมกันและขนานคุณควรพิจารณาใช้Task Parallel Library
แอปพลิเคชันถูกผูกมัด CPU เมื่อประสิทธิภาพทางคณิตศาสตร์ / ตรรกะ / จุดลอยตัว (A / L / FP) ในระหว่างการดำเนินการส่วนใหญ่อยู่ใกล้กับประสิทธิภาพสูงสุดตามทฤษฎีของโปรเซสเซอร์ (ข้อมูลที่ได้รับจากผู้ผลิตและกำหนดโดยลักษณะของ หน่วยประมวลผล: จำนวนแกนความถี่ลงทะเบียน ALUs FPU ฯลฯ )
ประสิทธิภาพแอบมองนั้นเป็นเรื่องยากมากที่จะประสบความสำเร็จในแอปพลิเคชันในโลกแห่งความเป็นจริงเพราะไม่สามารถบอกได้ว่าเป็นไปไม่ได้ แอปพลิเคชันส่วนใหญ่เข้าถึงหน่วยความจำในส่วนต่าง ๆ ของการดำเนินการและตัวประมวลผลไม่ได้ดำเนินการ A / L / FP ในช่วงหลายรอบ สิ่งนี้เรียกว่าข้อ จำกัด Von Neumannเนื่องจากระยะห่างระหว่างหน่วยความจำและโปรเซสเซอร์
หากคุณต้องการอยู่ใกล้กับ CPU ประสิทธิภาพสูงสุดกลยุทธ์อาจลองใช้ข้อมูลส่วนใหญ่ในแคชหน่วยความจำใหม่เพื่อหลีกเลี่ยงการต้องการข้อมูลจากหน่วยความจำหลัก อัลกอริทึมที่ใช้ประโยชน์จากคุณลักษณะนี้คือการคูณเมทริกซ์เมทริกซ์ (หากเมทริกซ์ทั้งสองสามารถเก็บไว้ในหน่วยความจำแคช) สิ่งนี้เกิดขึ้นเพราะถ้าเมทริกซ์มีขนาดn x n
คุณจำเป็นต้อง2 n^3
ดำเนินการเกี่ยวกับการดำเนินการโดยใช้2 n^2
ข้อมูลหมายเลข FP เท่านั้น ตัวอย่างเช่นการเพิ่มเมทริกซ์ในทางตรงกันข้ามคือการเชื่อมโยง CPU น้อยกว่าหรือแอปพลิเคชันที่ผูกมัดหน่วยความจำมากกว่าการคูณเมทริกซ์เนื่องจากมันต้องการเพียงn^2
FLOPs ที่มีข้อมูลเดียวกัน
ในรูปต่อไปนี้ FLOPs ที่ได้จากอัลกอริธึมไร้เดียงสาสำหรับการเพิ่มเมทริกซ์และการคูณเมทริกซ์ใน Intel i5-9300H แสดงดังนี้:
โปรดทราบว่าตามที่คาดไว้ประสิทธิภาพของการคูณเมทริกซ์จะยิ่งใหญ่กว่าการเพิ่มเมทริกซ์ ผลลัพธ์เหล่านี้สามารถทำซ้ำได้โดยการเรียกใช้test/gemm
และtest/matadd
มีอยู่ในที่เก็บนี้
ฉันขอแนะนำให้ดูวิดีโอที่ได้รับจาก J. Dongarra เกี่ยวกับผลกระทบนี้
I / O กระบวนการที่ถูกผูกไว้: - ถ้าส่วนใหญ่ของอายุการใช้งานของกระบวนการที่ใช้ในสถานะ i / o ดังนั้นกระบวนการนี้เป็นกระบวนการผูก ai / o กระบวนการตัวอย่าง: - เครื่องคำนวณ, Internet explorer
กระบวนการ CPU Bound: - หากส่วนใหญ่ของกระบวนการใช้งานในซีพียูส่วนใหญ่จะเป็นกระบวนการผูกซีพียู