เราควรใช้ความพยายามมากแค่ไหนในการเขียนโปรแกรมสำหรับหลายคอร์?


12

โปรเซสเซอร์กำลังเพิ่มจำนวนคอร์มากขึ้นในทุกวันนี้ซึ่งทำให้ฉันสงสัย ...

เราควรโปรแกรมเมอร์ปรับให้เข้ากับพฤติกรรมนี้และใช้ความพยายามมากขึ้นในการเขียนโปรแกรมสำหรับหลายแกน

เราควรทำและเพิ่มประสิทธิภาพสิ่งนี้ในระดับใด เกลียว? ความสัมพันธ์กัน? การปรับแต่งฮาร์ดแวร์ให้เหมาะสม? อื่น ๆ อีก?

คำตอบ:


15

ไม่ว่าคุณจะเก่งแค่ไหนมันก็ไม่น่าเป็นไปได้ที่คุณจะมีโครงร่างการจัดการเธรดที่ดีกว่าทีมที่พัฒนาภาษาและคอมไพเลอร์ที่คุณเขียนโค้ด

หากคุณต้องการให้แอปพลิเคชันของคุณเป็นแบบมัลติเธรดให้สร้างเธรดที่คุณต้องการและให้คอมไพเลอร์และระบบปฏิบัติการทำงานต่อไป

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

คุณต้องระวังสิ่งที่เกิดขึ้น (ดูความคิดเห็นของ Lorenzo) เพื่อให้คุณสามารถให้คำแนะนำกับการจัดการเธรด (หรือแทนที่ในกรณีพิเศษ) แต่ฉันคิดว่าสิ่งเหล่านี้จะมีน้อยมาก


3
แต่การที่เธรดกระโดดอย่างต่อเนื่องจากคอร์หนึ่งไปอีกอันจะมีการปรับประสิทธิภาพ (เนื่องจากพลาดแคช CPU ระดับที่หนึ่งและที่สอง) โดยเฉพาะอย่างยิ่งในสถาปัตยกรรมที่มีการตายทางกายภาพที่แตกต่างกันสองแบบ ในโค้ดที่มีหลายเธรดความสัมพันธ์เป็นสิ่งที่ดี
Wizard79

@ Lorenzo - ในกรณีนี้คุณจะต้องดูว่าคุณสามารถผูกเธรดกับแกนเดี่ยว - ซึ่งอาจเป็นกรณีพิเศษ - แต่สิ่งที่น่าสนใจ
ChrisF

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

ฉันเห็นด้วยกับ @JBRWilkinson, ความสัมพันธ์ของเธรดดูเหมือนว่างาน OS ให้ฉัน
Collin

1
@JBRWilkinson ภายใต้ linux (และฉันคิดว่าระบบปฏิบัติการส่วนใหญ่) หัวข้อกระโดดระหว่างแกนตลอดเวลา เหตุผลแรกคือคุณมีเธรดโดยรวมมากกว่าคอร์ และถ้าบางกระทู้ตายไปคุณต้องปรับสมดุล เหตุผลที่สองคือกระทู้จำนวนมากกำลังนอนหลับ และเมื่อบางคนตื่นขึ้นมาเคอร์เนลอาจคิดว่าหนึ่งคอร์มีภาระมากกว่าคนอื่นและย้ายเธรดบ่อยครั้งที่ซีพียูของคุณใช้เธรดการคำนวณ จากนั้น 2 cpu hogging threads ที่รันบนแกนเดียวกันจนกว่าเคอร์เนลจะเลื่อนหนึ่งอัน หากคุณแยกงานชิ้นใหญ่ออกเป็นชิ้นส่วน num-cores อย่างแน่นอนคุณต้องการตั้งค่าความสัมพันธ์ของเธรด
Goswin von Brederlow

5

ฉันเป็นโปรแกรมเมอร์. NET และฉันรู้ว่า. NET มี abstraction ระดับสูงสำหรับมัลติเธรดที่เรียกว่า Tasks มันช่วยปกป้องคุณไม่ให้รู้มากเกินไปเกี่ยวกับวิธีทำมัลติเธรดที่เหมาะสมกับโลหะ ฉันคิดว่าแพลตฟอร์มการพัฒนาอื่น ๆ ในปัจจุบันมี abstractions ที่คล้ายกัน ดังนั้นถ้าคุณจะทำทุกอย่างด้วยมัลติเธรดฉันจะพยายามทำงานในระดับนั้นถ้าเป็นไปได้

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

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


5

ในดินแดนแห่ง Objective-C และ Mac OS X และ iOS เฟรมเวิร์ก (เหมือนกับคนอื่น ๆ ) ถูกเขียนขึ้นเพื่อใช้ประโยชน์จากการเพิ่มขึ้นของคอร์โปรเซสเซอร์และนำเสนอนักพัฒนาด้วยอินเทอร์เฟซที่ดีเพื่อใช้ประโยชน์

ตัวอย่างบน Mac OS X และ iOS คือ Grand Central Dispatch มีการเพิ่มเติมไปยังlibc(ฉันเชื่อว่า) เพื่ออำนวยความสะดวกในคิวแบบมัลติเธรด จากนั้นกรอบงานของ Cocoa และ Foundation (รวมอยู่ในกรอบอื่น ๆ ) จะถูกเขียนไว้ด้านบนของ GCD ทำให้นักพัฒนาสามารถเข้าถึงการจัดคิวและทำเกลียวด้วยรหัสแผ่นหม้อน้ำน้อยมาก

หลายภาษาและกรอบงานมีแนวคิดที่คล้ายกัน


5

ส่วนที่ยากคือการแยกอัลกอริทึมที่ใช้ CPU ของคุณเข้ากับส่วนของการดำเนินการที่อาจเกิดขึ้นได้

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


3

ตอนนี้เรากำลัง (ตุลาคม 2010) ในช่วงเวลาแห่งการเปลี่ยนแปลงอันยิ่งใหญ่

วันนี้เราสามารถซื้อเดสก์ทอป 12 คอร์ได้
วันนี้เราสามารถซื้อการ์ดประมวลผลหลัก 448 (ค้นหา NVidia Tesla)

มีข้อ จำกัด ว่าผู้พัฒนาของเราสามารถทำงานในสภาพแวดล้อมที่ขนานกันอย่างมากมายโปรแกรมของเราจะทำงานได้ในอนาคตอันใกล้นี้

ระบบปฏิบัติการสภาพแวดล้อมรันไทม์และไลบรารีโปรแกรมสามารถทำได้มาก

ในอนาคตเราจะต้องแบ่งพาร์ติชันการประมวลผลของเราออกเป็นส่วนแยกสำหรับการประมวลผลอิสระโดยใช้ abstractions เช่น. NET "Task Framework" ใหม่

รายละเอียดเช่นการจัดการแคชและความสัมพันธ์จะยังคงปรากฏอยู่ แต่จะเป็นสิ่งที่พิสูจน์ได้ของแอปพลิเคชั่นที่มีประสิทธิภาพสูงเท่านั้น ไม่มีผู้พัฒนารายใดที่ต้องการจัดการรายละเอียดเหล่านี้ด้วยตนเองผ่านเครื่องหลัก 10k


3

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

สำหรับกรณีส่วนใหญ่ความเข้าใจที่มั่นคงและการใช้ล็อกเธรดและงานและกลุ่มงานจะเป็นการเริ่มต้นที่ดีเมื่อต้องการความขนาน (แตกต่างกันไปตาม lang / lib)

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

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

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

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

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

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

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


2

เราทำ แต่เราเขียนซอฟต์แวร์การคำนวณหนักเพื่อให้เราได้รับประโยชน์โดยตรงจากหลายคอร์

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


0

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

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

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

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