กลับไปหน้าบทความ

อ่าน 10 นาที

ซิลค์

Cilk , Cilk++ , Cilk Plus และ OpenCilk เป็น ภาษาโปรแกรม อเนกประสงค์ ที่ออกแบบมาสำหรับ การประมวลผลแบบขนาน หลายเธรด โดยมีพื้นฐานมาจาก ภาษาโปรแกรม C และ C++...

ซิลค์

ซิลค์
กระบวนทัศน์เชิงบังคับ ( เชิงกระบวนการ ) มีโครงสร้างขนานกัน
ออกแบบโดยห้องปฏิบัติการวิทยาศาสตร์คอมพิวเตอร์ของ MIT
นักพัฒนาอินเทล
ปรากฏครั้งแรกพ.ศ. 2537
วินัยในการพิมพ์คงที่อ่อนแอปรากฏชัด
เว็บไซต์cilk .mit .edu
ภาษาถิ่น
Cilk++, Cilk Plus, OpenCilk
ได้รับอิทธิพลจาก
ซี
ได้รับอิทธิพล
OpenMP 3.0, [ 1 ] Rayon ( ไลบรารี Rust ) [ 2 ]
โอเพ่นซิลค์
ออกแบบโดยเอ็มไอที
นักพัฒนาเอ็มไอที
ปรากฏครั้งแรก2020
เวอร์ชันเสถียร
2.0.1 / 3 กันยายน 2022 ( 3 กันยายน 2022 )
โอเอสระบบคล้าย Unix , macOS
ใบอนุญาตเอ็มไอที
เว็บไซต์www.opencilk.org
ซิลค์พลัส
ออกแบบโดยอินเทล
นักพัฒนาอินเทล
ปรากฏครั้งแรก2010
เวอร์ชันเสถียร
1.2 / 9 กันยายน 2556 ( 9 กันยายน 2013 )
นามสกุลไฟล์(เหมือนกับภาษา C หรือ C++)
เว็บไซต์http://cilkplus.org/

Cilk , Cilk++ , Cilk PlusและOpenCilkเป็นภาษาโปรแกรมอเนกประสงค์ ที่ออกแบบมาสำหรับการประมวลผลแบบขนานหลายเธรดโดยมีพื้นฐานมาจาก ภาษาโปรแกรม CและC++ซึ่งได้ขยายเพิ่มเติมด้วยโครงสร้างเพื่อแสดงลูปแบบขนานและรูปแบบการแยกและรวม ( fork–join )

Cilk ถูกพัฒนาขึ้นครั้งแรกในช่วงทศวรรษ 1990 ที่สถาบันเทคโนโลยีแมสซาชูเซตส์ (MIT) โดยกลุ่มของCharles E. Leisersonต่อมาได้ถูกนำไปจำหน่ายในเชิงพาณิชย์ในชื่อ Cilk++ โดยบริษัทที่แยกตัวออกมาชื่อ Cilk Arts บริษัทดังกล่าวถูกIntel เข้าซื้อกิจการในเวลาต่อมา และ Intel ได้เพิ่มความเข้ากันได้กับโค้ด C และ C++ ที่มีอยู่เดิม โดยเรียกผลลัพธ์ว่า Cilk Plus หลังจากที่ Intel หยุดให้การสนับสนุน Cilk Plus ในปี 2017 MIT ก็ได้พัฒนา Cilk ขึ้นมาใหม่ในรูปแบบของ OpenCilk

ประวัติศาสตร์

MIT Cilk

ภาษาการเขียนโปรแกรม Cilk พัฒนามาจากโครงการแยกกัน 3 โครงการที่ห้องปฏิบัติการวิทยาศาสตร์คอมพิวเตอร์ของ MIT: [ 3 ]

  • งานวิจัยเชิงทฤษฎีเกี่ยวกับการจัดตารางเวลาสำหรับแอปพลิเคชันแบบมัลติเธรด
  • StarTech – โปรแกรมหมากรุกแบบขนานที่สร้างขึ้นเพื่อใช้งานบนเครื่อง Connection Machine รุ่น CM-5 ของบริษัท Thinking Machines Corporation
  • PCM/Threaded-C – แพ็กเกจที่เขียนด้วยภาษา C สำหรับการจัดตารางการทำงานของเธรดแบบ continuation-passing บน CM-5

ในเดือนเมษายน พ.ศ. 2537 โครงการทั้งสามได้ถูกรวมเข้าด้วยกันและตั้งชื่อว่า "Cilk" ชื่อ Cilk ไม่ใช่คำย่อ แต่เป็นการอ้างอิงถึง "เส้นใยละเอียด" ( silk ) และภาษาโปรแกรม C คอมไพเลอร์ Cilk-1 ได้ถูกปล่อยออกมาในเดือนกันยายน พ.ศ. 2537

ภาษา Cilk ดั้งเดิมนั้นอิงตามภาษาANSI Cโดยมีการเพิ่มคำหลักเฉพาะของ Cilk เพื่อบ่งบอกถึงการทำงานแบบขนาน เมื่อลบคำหลักของ Cilk ออกจากซอร์สโค้ดของ Cilk ผลลัพธ์ที่ได้ควรจะเป็นโปรแกรม C ที่ถูกต้องเสมอ ซึ่งเรียกว่าserial elision (หรือC elision ) ของโปรแกรม Cilk แบบเต็ม โดยมีความหมายเหมือนกับโปรแกรม Cilk ที่ทำงานบนโปรเซสเซอร์ตัวเดียว แม้จะมีหลายสิ่งที่คล้ายคลึงกัน แต่ Cilk ก็ไม่ได้เกี่ยวข้องโดยตรงกับ Concurrent Cของ AT&T Bell Labs

Cilk ถูกนำมาใช้เป็นตัวแปลภาษา C โดยมีเป้าหมายที่คอมไพเลอร์ GNU C (GCC) เวอร์ชันล่าสุด Cilk 5.4.6 มีให้บริการจากห้องปฏิบัติการวิทยาศาสตร์คอมพิวเตอร์และปัญญาประดิษฐ์ของ MIT (CSAIL) แต่ไม่ได้รับการสนับสนุนอีกต่อไป[ 4 ]

โปรแกรมเล่นหมากรุกคู่ขนาน Cilkchess เป็นตัวอย่างที่แสดงให้เห็นถึงความสามารถของ Cilk ซึ่งได้รับรางวัลหมากรุกคอมพิวเตอร์หลายรายการในช่วงทศวรรษ 1990 รวมถึงการแข่งขันหมากรุกคอมพิวเตอร์โอเพ่นแห่งเนเธอร์แลนด์ในปี 1996 [ 5 ]

ซิลค์ อาร์ตส์ และ ซิลค์++

ก่อนปี ค.ศ. 2549ตลาดของ Cilk จำกัดอยู่เฉพาะในด้านการประมวลผลประสิทธิภาพสูง การเกิดขึ้นของโปรเซสเซอร์มัลติคอร์ในการประมวลผลทั่วไปหมายความว่ามีการจัดส่งคอมพิวเตอร์แบบขนานใหม่หลายร้อยล้านเครื่องทุกปี Cilk Arts ก่อตั้งขึ้นเพื่อใช้ประโยชน์จากโอกาสนั้น: ในปี 2549 Leiserson ได้เปิดตัว Cilk Arts เพื่อสร้างและนำเสนอ Cilk เวอร์ชันใหม่สู่ตลาดที่รองรับความต้องการเชิงพาณิชย์ของโปรแกรมเมอร์รุ่นใหม่ บริษัทปิดรอบการระดมทุน Series A ในเดือนตุลาคม 2550 และผลิตภัณฑ์ Cilk++ 1.0 ก็เริ่มวางจำหน่ายในเดือนธันวาคม 2551

Cilk++ แตกต่างจาก Cilk ในหลายด้าน ได้แก่ การรองรับภาษา C++, การรองรับลูป และไฮเปอร์ออบเจ็กต์  ซึ่งเป็นโครงสร้างใหม่ที่ออกแบบมาเพื่อแก้ปัญหาการแข่งขันของข้อมูลที่เกิดจากการเข้าถึงตัวแปรส่วนกลางแบบขนาน Cilk++ เป็นซอฟต์แวร์กรรมสิทธิ์เช่นเดียวกับรุ่นก่อนหน้า มันถูกพัฒนาขึ้นในรูปแบบคอมไพเลอร์จาก Cilk ไปเป็น C++ โดยรองรับ คอมไพเลอร์ ของ Microsoftและ GNU

อินเทล ซิลค์ พลัส

เมื่อวันที่ 31 กรกฎาคม 2552 Cilk Arts ประกาศบนเว็บไซต์ของตนว่าผลิตภัณฑ์และทีมวิศวกรรมของบริษัทเป็นส่วนหนึ่งของIntel Corp. แล้ว ในช่วงต้นปี 2553 เว็บไซต์ Cilk www.cilk.comเริ่มเปลี่ยนเส้นทางไปยังเว็บไซต์ของ Intel (ณ ต้นปี 2560 เว็บไซต์ Cilk เดิมไม่แสดงเส้นทางไปยังโฮสต์ใดๆ อีกต่อไป) Intel และ Cilk Arts ได้บูรณาการและพัฒนาเทคโนโลยีเพิ่มเติม ส่งผลให้มีการเปิดตัว Intel Cilk Plusใน เดือนกันยายน 2553 [ 6 ] [ 7 ] Cilk Plus ใช้การลดความซับซ้อนที่เสนอโดย Cilk Arts ใน Cilk++ เพื่อขจัดความจำเป็นในการใช้คำหลัก Cilk เดิมหลายคำ ในขณะเดียวกันก็เพิ่มความสามารถในการสร้างฟังก์ชันและจัดการกับตัวแปรที่เกี่ยวข้องกับการดำเนินการลดรูป Cilk Plus แตกต่างจาก Cilk และ Cilk++ โดยการเพิ่มส่วนขยายอาร์เรย์ การรวมเข้ากับคอมไพเลอร์เชิงพาณิชย์ (จาก Intel) และความเข้ากันได้กับดีบักเกอร์ที่มีอยู่[ 8 ]

Cilk Plus ถูกนำมาใช้ครั้งแรกในIntel C++ Compilerพร้อมกับการเปิดตัว Intel Compiler ใน Intel Composer XE 2010 Intel ได้บริจาคการใช้งาน แบบโอเพนซอร์ส ( ได้รับอนุญาตภายใต้ BSD ) ให้กับ GNU Compiler Collection (GCC) ซึ่งได้รวมการสนับสนุน Cilk Plus ไว้ในเวอร์ชัน 4.9 [ 9 ]ยกเว้น คีย์เวิร์ด _Cilk_forซึ่งถูกเพิ่มเข้ามาใน GCC 5.0 ในเดือนกุมภาพันธ์ 2013 Intel ได้ประกาศClang forkที่รองรับ Cilk Plus [ 10 ] Intel Compiler แต่ไม่ใช่การใช้งานแบบโอเพนซอร์ส มาพร้อมกับตัวตรวจจับการแข่งขันและตัววิเคราะห์ประสิทธิภาพ

ต่อมา Intel ได้ยกเลิกการใช้งาน โดยแนะนำให้ผู้ใช้เปลี่ยนไปใช้OpenMPหรือไลบรารี TBB ของ Intel เองสำหรับความต้องการการเขียนโปรแกรมแบบขนานแทน[ 11 ]

ความแตกต่างระหว่างเวอร์ชัน

ในการใช้งาน Cilk เวอร์ชันดั้งเดิมของ MIT คำหลักแรกของ Cilk คือ `procedure` cilkซึ่งระบุฟังก์ชันที่เขียนด้วยภาษา Cilk เนื่องจากขั้นตอนการทำงานของ Cilk สามารถเรียกใช้ขั้นตอนการทำงานของ C ได้โดยตรง แต่ขั้นตอนการทำงานของ C ไม่สามารถเรียกใช้หรือสร้างขั้นตอนการทำงานของ Cilk ได้โดยตรง คำหลักนี้จึงจำเป็นเพื่อแยกแยะโค้ด Cilk ออกจากโค้ด C Cilk Plus ได้ลบข้อจำกัดนี้ออกไป รวมถึงcilkคำหลัก `procedure` ด้วย ดังนั้นฟังก์ชัน C และ C++ จึงสามารถเรียกใช้โค้ด Cilk Plus และในทางกลับกันได้

การยกเลิกการใช้งาน Cilk Plus

ในเดือนพฤษภาคม พ.ศ. 2560 GCC 7.1 ได้รับการเผยแพร่และระบุว่าการสนับสนุน Cilk Plus ถูกยกเลิก[ 12 ] Intel เองก็ประกาศในเดือนกันยายน พ.ศ. 2560 ว่าจะยกเลิกการสนับสนุน Cilk Plus ในการเผยแพร่ Intel Software Development Tools ในปี พ.ศ. 2561 [ 11 ]ในเดือนพฤษภาคม พ.ศ. 2561 GCC 8.1 ได้รับการเผยแพร่โดยได้ลบการสนับสนุน Cilk Plus ออกไปแล้ว[ 13 ]

โอเพ่นซิลค์

หลังจากที่ Intel ยกเลิกการสนับสนุน Cilk Plus แล้ว MIT ก็ได้เข้ามารับช่วงการพัฒนา Cilk ในการใช้งาน OpenCilk โดยมุ่งเน้นที่ LLVM/Clang ซึ่งปัจจุบันเรียกว่า "Tapir" [ 11 ] [ 14 ] OpenCilk ยังคงเข้ากันได้กับ Intel Cilk Plus เป็นส่วนใหญ่[ 15 ]เวอร์ชันเสถียรเวอร์ชันแรกได้รับการเผยแพร่ในเดือนมีนาคม 2021 [ 16 ]

ลักษณะทางภาษา

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

การทำงานแบบขนาน: การสร้างและการซิงค์

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

  • คำ ว่า spawnเมื่อนำหน้าการเรียกฟังก์ชัน ( spawn f(x) ) จะบ่งชี้ว่าการเรียกฟังก์ชัน ( f(x) ) สามารถทำงานแบบขนานกับคำสั่งที่ตามมาในฟังก์ชันที่เรียกได้อย่างปลอดภัย โปรดทราบว่าตัวจัดตารางการทำงานไม่จำเป็นต้องเรียกใช้กระบวนการนี้แบบขนานเสมอไป คำว่า spawn เพียงแค่แจ้งให้ตัวจัดตารางการทำงานทราบว่าสามารถทำเช่นนั้นได้
  • คำ สั่ง syncบ่งชี้ว่าการทำงานของฟังก์ชันปัจจุบันจะไม่สามารถดำเนินต่อไปได้จนกว่าการเรียกใช้ฟังก์ชันก่อนหน้านี้ทั้งหมดจะเสร็จสมบูรณ์ นี่เป็นตัวอย่างของเมธอดแบบกั้น (barrier method)

(ใน Cilk Plus คำหลักจะสะกดว่า_Cilk_spawnและ_Cilk_syncหรือcilk_spawnและcilk_syncหากมีการรวมส่วนหัวของ Cilk Plus ไว้ด้วย)

ด้านล่างนี้คือตัวอย่างการใช้ งานฟังก์ชัน ฟิโบนาชชีแบบเรียกซ้ำในภาษา Cilk โดยมีการเรียกซ้ำแบบขนาน ซึ่งแสดงให้เห็นถึงการใช้ คีย์เวิร์ด `spawn`และ`sync` Cilk เวอร์ชันดั้งเดิมกำหนดให้ฟังก์ชันใดๆ ที่ใช้คีย์เวิร์ดเหล่านี้ต้องมีคำอธิบายประกอบด้วย คีย์เวิร์ด `cilk`ซึ่งถูกลบออกไปแล้วใน Cilk Plus (โค้ดโปรแกรม Cilk ไม่ได้มีการกำหนดหมายเลขไว้ หมายเลขเหล่านี้ถูกเพิ่มเข้ามาเพื่อให้การอธิบายเข้าใจง่ายขึ้นเท่านั้น)

cilk int fib ( int n ) {ถ้า( n < 2 ) {ส่งคืนค่าn ;}อื่น{int x , y ;x = spawn fib ( n - 1 );y = spawn fib ( n - 2 );ซิงค์;ส่งคืนค่าx + y ;}}

หากโค้ดนี้ถูกประมวลผลโดย โปรเซสเซอร์ ตัวเดียวเพื่อหาค่าของfib(2)โปรเซสเซอร์นั้นจะสร้างเฟรมสำหรับfib(2)และประมวลผลบรรทัดที่ 1 ถึง 5 ในบรรทัดที่ 6 โปรเซสเซอร์จะสร้างช่องว่างในเฟรมเพื่อเก็บค่าของxและyในบรรทัดที่ 8 โปรเซสเซอร์จะต้องระงับเฟรมปัจจุบัน สร้างเฟรมใหม่เพื่อประมวลผลขั้นตอนfib(1)ประมวลผลโค้ดของเฟรมนั้นจนกว่าจะถึงคำสั่ง return แล้วจึงกลับมาทำงานต่อใน เฟรม fib(2)โดยใส่ค่าของ fib(1) ลงใน ตัวแปร xของfib(2)ในบรรทัดถัดไป โปรเซสเซอร์จะต้องระงับอีกครั้งเพื่อประมวลผลfib(0)และใส่ผลลัพธ์ลงในตัวแปร yของfib(2)

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

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

หากโปรเซสเซอร์ที่กำลังดำเนินการfib(2)ดำเนินการบรรทัดที่ 13 ก่อนที่โปรเซสเซอร์อีกสองตัวจะเสร็จสิ้นเฟรมของตน มันจะสร้างผลลัพธ์ที่ไม่ถูกต้องหรือข้อผิดพลาดfib(2)จะพยายามบวกค่าที่เก็บไว้ในxและyแต่ค่าใดค่าหนึ่งหรือทั้งสองค่าจะหายไป นี่คือจุดประสงค์ของ คำหลัก syncซึ่งเราเห็นในบรรทัดที่ 11: มันบอกโปรเซสเซอร์ที่กำลังดำเนินการเฟรมว่าต้องระงับการทำงานของตัวเองจนกว่าการเรียกใช้โปรซีเดอร์ทั้งหมดที่มันสร้างขึ้นจะส่งคืนค่า เมื่อfib(2)ได้รับอนุญาตให้ดำเนินการต่อไปหลังจาก คำสั่ง syncในบรรทัดที่ 11 จะเป็นไปได้ก็ต่อเมื่อfib(1)และfib(0)เสร็จสิ้นและใส่ผลลัพธ์ลงในxและyแล้ว ทำให้ปลอดภัยที่จะทำการคำนวณกับผลลัพธ์เหล่านั้น

ตัวอย่างโค้ดข้างต้นใช้ไวยากรณ์ของ Cilk-5 Cilk ดั้งเดิม (Cilk-1) ใช้ไวยากรณ์ที่แตกต่างออกไปซึ่งต้องใช้การเขียนโปรแกรมในรูปแบบการส่งผ่านความต่อเนื่อง อย่างชัดเจน และตัวอย่าง Fibonacci มีลักษณะดังนี้: [ 17 ]

thread fib ( cont int k , int n ) { if ( n < 2 ) { send_argument ( k , n ); } else { cont int x , y ; spawn_next sum ( k , ? x , ? y ); spawn fib ( x , n - 1 ); spawn fib ( y , n - 2 ); } }thread sum ( cont int k , int x , int y ) { send_argument ( k , x + y ); }

ภายในกรณีเรียกซ้ำของฟังก์ชันfib คำหลัก spawn_nextบ่งชี้ถึงการสร้าง เธรด ผู้สืบทอด (ตรงข้ามกับ เธรด ลูกที่สร้างโดยspawn ) ซึ่งจะเรียกใช้ ซับรูทีน sumหลังจากรอให้ตัวแปรต่อเนื่องxและyถูกเติมค่าโดยการเรียกซ้ำ กรณีพื้นฐานและsumใช้ การดำเนินการ send_argument(k, n)เพื่อตั้งค่าตัวแปรต่อเนื่องkให้เป็นค่าของnซึ่งเป็นการ "ส่งคืน" ค่าไปยังเธรดผู้สืบทอดอย่างมีประสิทธิภาพ

อ่าว

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

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

  • คำสำคัญ นี้inletใช้ระบุฟังก์ชันที่กำหนดไว้ภายในกระบวนการว่าเป็นอินพุต
  • คำสำคัญ นี้abortสามารถใช้ได้เฉพาะภายในอินเล็ตเท่านั้น โดยจะบอกตัวจัดตารางเวลาว่าขั้นตอนอื่นๆ ที่ถูกสร้างขึ้นจากขั้นตอนหลักนั้นสามารถยกเลิกได้อย่างปลอดภัย

ช่องทางเข้าถูกถอดออกเมื่อ Cilk เปลี่ยนชื่อเป็น Cilk++ และไม่มีอยู่ใน Cilk Plus

วงวนขนาน

Cilk++ ได้เพิ่มโครงสร้างเพิ่มเติมอีกอย่างหนึ่ง คือ ลูปแบบขนาน ซึ่งใน Cilk Plus ใช้สัญลักษณ์ cilk_for ลูปเหล่านี้มีลักษณะดังนี้

void loop ( int * a , int n ){#pragma cilk grainsize = 100 // ตัวเลือกเสริมcilk_for ( int i = 0 ; i < n ; i ++ ) {a [ i ] = f ( a [ i ]);}}

นี่เป็นการนำ สำนวน แผนที่แบบขนาน มาใช้ : ตัวลูป ซึ่งในที่นี้คือการเรียกfตามด้วยการกำหนดค่าให้กับอาร์เรย์aจะถูกดำเนินการสำหรับแต่ละค่าของiตั้งแต่ศูนย์ถึงnในลำดับที่ไม่แน่นอนคำสั่งเสริม "grain size" จะกำหนดการแบ่งย่อย : อาร์เรย์ย่อยใดๆ ที่มีองค์ประกอบหนึ่งร้อยหรือน้อยกว่าจะถูกประมวลผลตามลำดับ แม้ว่าข้อกำหนดของ Cilk จะไม่ได้ระบุพฤติกรรมที่แน่นอนของโครงสร้าง แต่การใช้งานทั่วไปคือการเรียกซ้ำแบบแบ่งและพิชิต[ 18 ]ราวกับว่าโปรแกรมเมอร์ได้เขียนไว้

static void recursion ( int * a , int start , int end ) { if ( end - start <= 100 ) { // 100 ในที่นี้คือขนาดเกรนfor ( int i = start ; i < end ; i ++ ) { a [ i ] = f ( a [ i ]); } } else { int midpoint = start + ( end - start ) / 2 ; cilk_spawn recursion ( a , start , midpoint ); recursion ( a , midpoint , end ); cilk_sync ; } }void loop ( int * a , int n ) { recursion ( a , 0 , n ); }

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

จากการตรวจสอบโครงสร้างลูปแบบขนานต่างๆ บน HPCwire พบว่า โครงสร้าง cilk_forค่อนข้างทั่วไป แต่สังเกตว่าข้อกำหนด Cilk Plus ไม่ได้กำหนดว่าการวนซ้ำจะต้องเป็นอิสระจากข้อมูล ดังนั้นคอมไพเลอร์จึงไม่สามารถแปลง ลูป cilk_for ให้ เป็น เวกเตอร์โดยอัตโนมัติได้ การตรวจสอบยังสังเกตข้อเท็จจริงที่ว่าการลดรูป (เช่น ผลรวมของอาร์เรย์) ต้องใช้โค้ดเพิ่มเติม[ 18 ]

ตัวลดขนาดและไฮเปอร์ออบเจ็กต์

Cilk++ ได้เพิ่มวัตถุประเภทหนึ่งที่เรียกว่าไฮเปอร์ออบเจ็กต์ซึ่งช่วยให้สายหลายสายสามารถแชร์สถานะได้โดยไม่มีเงื่อนไขการแข่งขันและไม่ต้องใช้การล็อกที่ชัดเจน แต่ละสายจะมีมุมมองบนไฮเปอร์ออบเจ็กต์ที่สามารถใช้และอัปเดตได้ เมื่อสายต่างๆ ซิงโครไนซ์กัน มุมมองจะถูกรวมเข้าด้วยกันในลักษณะที่โปรแกรมเมอร์กำหนด[ 20 ]

ไฮเปอร์ออบเจ็กต์ประเภทที่พบได้บ่อยที่สุดคือ รีดิวเซอร์ ซึ่งสอดคล้องกับเงื่อนไขการลดรูปในOpenMPหรือแนวคิดทางพีชคณิตของโมโนอิด รีดิวเซอร์แต่ละตัวมีองค์ประกอบเอกลักษณ์และตัวดำเนินการเชื่อมโยงที่รวมค่าสองค่าเข้าด้วยกัน รีดิวเซอร์ต้นแบบคือการบวกตัวเลข: องค์ประกอบเอกลักษณ์คือศูนย์ และ ตัวดำเนิน การลดรูป เชื่อมโยง จะคำนวณผลรวม รีดิวเซอร์นี้มีอยู่ใน Cilk++ และ Cilk Plus:

// คำนวณ ∑ foo(i) สำหรับ i ตั้งแต่ 0 ถึง N แบบขนานcilk :: reducer_opadd < float > result ( 0 ); cilk_for ( int i = 0 ; i < N ; i ++ ) result += foo ( i );

สามารถใช้ตัวลดรูปอื่นๆ เพื่อสร้างรายการเชื่อมโยงหรือสตริงได้ และโปรแกรมเมอร์สามารถกำหนดตัวลดรูปที่กำหนดเองได้

ข้อจำกัดของไฮเปอร์ออบเจ็กต์คือให้ความแน่นอน ที่จำกัด Burckhardt และคณะชี้ให้เห็นว่าแม้แต่ตัวลดผลรวมก็อาจส่งผลให้เกิดพฤติกรรมที่ไม่แน่นอนได้ โดยแสดงให้เห็นโปรแกรมที่อาจสร้างผลลัพธ์เป็น1หรือ2ขึ้นอยู่กับลำดับการจัดกำหนดการ: [ 21 ]

void add1 ( cilk :: reducer_opadd < int > & r ) { r ++ ; } // ... cilk :: reducer_opadd < int > r ( 0 ); cilk_spawn add1 ( r ); if ( r == 0 ) { r ++ ; } cilk_sync ; output ( r . get_value ());

สัญกรณ์อาร์เรย์

Intel Cilk Plus เพิ่มสัญลักษณ์เพื่อแสดงการดำเนินการระดับสูงบนอาร์เรย์ทั้งหมดหรือส่วนต่างๆ ของอาร์เรย์เช่น ฟังก์ชันแบบ axpyที่ปกติเขียนในรูปแบบ

// y ← α x + y void axpy ( int n , float alpha , const float * x , float * y ) { for ( int i = 0 ; i < n ; i ++ ) { y [ i ] += alpha * x [ i ]; } }

สามารถแสดงออกมาใน Cilk Plus ได้ดังนี้

y[0:n] += alpha * x[0:n]; 

สัญลักษณ์นี้ช่วยให้คอมไพเลอร์สามารถแปลงแอปพลิเคชันให้เป็นเวกเตอร์ได้อย่างมีประสิทธิภาพ Intel Cilk Plus อนุญาตให้ใช้การดำเนินการ C/C++ กับองค์ประกอบอาร์เรย์หลายตัวพร้อมกัน และยังมีฟังก์ชันในตัวชุดหนึ่งที่สามารถใช้ในการเลื่อน การหมุน และการลดขนาดแบบเวกเตอร์ได้ ฟังก์ชันการทำงานที่คล้ายกันนี้มีอยู่ในFortran 90แต่ Cilk Plus แตกต่างตรงที่ไม่จัดสรรอาร์เรย์ชั่วคราว ดังนั้นจึงคาดการณ์การใช้หน่วยความจำได้ง่ายกว่า

ฟังก์ชันพื้นฐาน

ใน Cilk Plus ฟังก์ชันพื้นฐาน (elemental function) คือฟังก์ชันปกติที่สามารถเรียกใช้ได้ทั้งกับอาร์กิวเมนต์แบบสเกลาร์หรือกับองค์ประกอบของอาร์เรย์แบบขนาน ฟังก์ชันเหล่านี้คล้ายกับฟังก์ชันเคอร์เนล (kernel functions) ใน OpenCL

#pragma simd

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

การขโมยงาน

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

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

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

ดูเพิ่มเติม

  • เว็บไซต์อย่างเป็นทางการของ OpenCilk
  • เว็บไซต์ Cilk Plus ของ Intel
  • เว็บไซต์โครงการ Cilk ที่ MIT
  • Arch D. Robison, "Cilk Plus: การสนับสนุนภาษาสำหรับการประมวลผลแบบขนานด้วยเธรดและเวกเตอร์"และ"การเขียนโปรแกรมแบบขนานด้วย Cilk Plus" , 16 กรกฎาคม 2012
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Cilk&oldid=1324325180#History "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ซิลค์

Cilk , Cilk++ , Cilk Plus และ OpenCilk เป็น ภาษาโปรแกรม อเนกประสงค์ ที่ออกแบบมาสำหรับ การประมวลผลแบบขนาน หลายเธรด โดยมีพื้นฐานมาจาก ภาษาโปรแกรม C และ C++...

MIT Cilk

ภาษาการเขียนโปรแกรม Cilk พัฒนามาจากโครงการแยกกัน 3 โครงการที่ห้องปฏิบัติการวิทยาศาสตร์คอมพิวเตอร์ของ MIT: [ 3 ]

ซิลค์ อาร์ตส์ และ ซิลค์++

ก่อน ปี ค.ศ. 2549 ตลาดของ Cilk จำกัดอยู่เฉพาะในด้านการประมวลผลประสิทธิภาพสูง การเกิดขึ้นของโปรเซสเซอร์มัลติคอร์ในการประมวลผลทั่วไปหมายความว่ามีการจัดส่งคอมพิวเตอร์แบบขนานใหม่หลายร้อยล้านเครื่องทุกปี Cilk Arts ก่อตั้งขึ้นเพื่อใช้ประโยชน์จากโอกาสนั้น: ในปี 2549...

อินเทล ซิลค์ พลัส

เมื่อวันที่ 31 กรกฎาคม 2552 Cilk Arts ประกาศบนเว็บไซต์ของตนว่าผลิตภัณฑ์และทีมวิศวกรรมของบริษัทเป็นส่วนหนึ่งของ Intel Corp. แล้ว ในช่วงต้นปี 2553 เว็บไซต์ Cilk www.cilk.