การเขียนโปรแกรมเชิงหน้าที่และการคำนวณทางวิทยาศาสตร์


42

ฉันขอโทษถ้านี่เป็นคำถามที่คลุมเครือ แต่นี่จะไป:

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

ข้อดีและข้อเสียของการตั้งโปรแกรมการทำงานในโดเมน SciComp คืออะไร


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

คำตอบ:


34

ฉันเพิ่งเขียนโปรแกรมฟังก์ชั่นเพียงเล็กน้อยดังนั้นให้ตอบด้วยเกลือเม็ดหนึ่ง

ข้อดี:

  • การเขียนโปรแกรมฟังก์ชั่นมีลักษณะทางคณิตศาสตร์มาก เป็นกระบวนทัศน์ที่ดีสำหรับการแสดงแนวคิดทางคณิตศาสตร์บางอย่าง
  • มีห้องสมุดที่ดีสำหรับสิ่งต่าง ๆ เช่นการตรวจสอบอย่างเป็นทางการของโปรแกรมและการพิสูจน์ทฤษฎีบทดังนั้นจึงเป็นไปได้ที่จะเขียนโปรแกรมด้วยเหตุผลเกี่ยวกับโปรแกรม - แง่มุมนี้ดีสำหรับการทำซ้ำ
  • คุณสามารถเขียนโปรแกรมใช้งานได้ใน Python และ C ++ ผ่านการแสดงออกแลมบ์ดา คุณยังสามารถเขียนโปรแกรมใช้งานได้ใน Julia และ Mathematica
  • มีคนไม่มากที่ใช้มันดังนั้นคุณสามารถเป็นผู้บุกเบิก เหมือนกับที่มีผู้ใช้งานในช่วงต้นของ MATLAB, Python, R และตอนนี้ Julia จำเป็นต้องมีผู้เริ่มต้นใช้งานการเขียนโปรแกรมแบบใช้งานได้ก่อนเพื่อให้ทัน

จุดด้อย:

  • ภาษาที่โดยทั่วไปคิดว่าเป็นภาษาโปรแกรมที่ใช้งานได้เช่น Haskell, OCaml (และ ML ภาษาถิ่นอื่น ๆ ) และ Lisp มักคิดว่าเป็นภาษาที่ช้าเมื่อเทียบกับภาษาที่ใช้สำหรับการคำนวณทางวิทยาศาสตร์ที่มีประสิทธิภาพสูง OCaml นั้นดีที่สุดประมาณครึ่งหนึ่งเร็วเท่า C
  • ภาษาเหล่านี้ขาดโครงสร้างพื้นฐานของห้องสมุดเมื่อเทียบกับภาษาที่ใช้กันทั่วไปในวิทยาศาสตร์การคำนวณ (Fortran, C, C ++, Python) ถ้าคุณต้องการที่จะแก้ PDE มันเป็นวิธีที่ง่ายกว่าที่จะทำในภาษาที่ใช้กันทั่วไปในวิทยาศาสตร์การคำนวณมากกว่าที่ไม่ได้เป็น
  • มีชุมชนวิทยาศาสตร์การคำนวณไม่มากนักที่ใช้ภาษาโปรแกรมที่ใช้งานได้เนื่องจากมีการใช้ภาษาเชิงปฏิบัติซึ่งหมายความว่าคุณจะไม่ได้รับความช่วยเหลือมากมายในการเรียนรู้หรือแก้ไขจุดบกพร่องและผู้คนอาจจะให้คุณอึ ใช้มัน (ไม่ว่าคุณจะสมควรหรือไม่ก็ตาม)
  • รูปแบบของการเขียนโปรแกรมเชิงหน้าที่แตกต่างจากรูปแบบที่ใช้ในการเขียนโปรแกรมตามขั้นตอนซึ่งโดยทั่วไปจะสอนในชั้นเรียนวิทยาศาสตร์คอมพิวเตอร์เบื้องต้นและใน "MATLAB สำหรับนักวิทยาศาสตร์และวิศวกร" - ประเภทของชั้นเรียน

ฉันคิดว่าการคัดค้านจำนวนมากในส่วน "จุดด้อย" อาจเอาชนะได้ ดังที่เป็นจุดร่วมของการสนทนาบนไซต์แลกเปลี่ยนแลกเปลี่ยนเวลานักพัฒนาซอฟต์แวร์มีความสำคัญมากกว่าเวลาดำเนินการ แม้ว่าภาษาโปรแกรมเชิงฟังก์ชั่นจะทำงานช้าหากส่วนที่สำคัญต่อประสิทธิภาพสามารถมอบหมายให้กับภาษาเชิงกระบวนงานที่รวดเร็วขึ้นและหากสามารถแสดงให้เห็นถึงการเพิ่มผลิตภาพจากการพัฒนาแอพพลิเคชั่นอย่างรวดเร็ว เป็นที่น่าสังเกตว่าโปรแกรมที่ใช้งานใน Python ล้วน ๆ , MATLAB บริสุทธิ์และ pure R นั้นช้ากว่าการนำไปใช้ของโปรแกรมเดียวกันนี้ใน C, C ++ หรือ Fortran ภาษาเช่น Python, MATLAB และ R เป็นที่นิยมอย่างแม่นยำเพราะพวกมันแลกเปลี่ยนความเร็วในการประมวลผลเพื่อเพิ่มประสิทธิภาพ Python และ MATLAB ทั้งสองมีสิ่งอำนวยความสะดวกสำหรับการใช้งานอินเทอร์เฟซกับรหัสที่คอมไพล์ใน C หรือ C ++ เพื่อให้โค้ดที่มีประสิทธิภาพที่สำคัญสามารถนำไปใช้เพื่อดำเนินการได้อย่างรวดเร็ว ภาษาส่วนใหญ่มีอินเตอร์เฟซฟังก์ชันต่างประเทศกับ C ซึ่งเพียงพอที่จะเชื่อมต่อกับห้องสมุดส่วนใหญ่ที่สนใจกับนักวิทยาศาสตร์ด้านการคำนวณ

คุณควรมีความสนใจในการเขียนโปรแกรมการทำงานหรือไม่?

ทุกอย่างขึ้นอยู่กับสิ่งที่คุณคิดว่าเจ๋ง หากคุณเป็นคนประเภทที่ยินดีที่จะร่วมประชุมและคุณยินดีที่จะพูดคุยกับผู้คนเกี่ยวกับคุณธรรมของสิ่งที่คุณต้องการจะทำด้วยการเขียนโปรแกรมที่ใช้งานได้ฉันจะบอกว่า . ฉันชอบที่จะเห็นคนทำสิ่งที่ยอดเยี่ยมด้วยการเขียนโปรแกรมฟังก์ชั่นในวิทยาศาสตร์การคำนวณถ้าไม่มีเหตุผลอื่นนอกจากที่จะพิสูจน์ความผิดพลาดของบรรดาชาวเนย์ส (และจะมีจำนวนมากของผู้บรรยาย) หากคุณไม่ได้เป็นคนประเภทที่ต้องการที่จะจัดการกับพวงของคนที่ขอให้คุณ "ทำไมในนรกที่คุณใช้ภาษาการเขียนโปรแกรมการทำงานแทน (แทรกภาษาการเขียนโปรแกรมของพวกเขาชื่นชอบในการดำเนินการที่นี่)?" แล้วฉัน wouldn' ไม่รำคาญ

มีการใช้ภาษาการเขียนโปรแกรมเพื่อการทำงานที่เน้นการจำลองสถานการณ์ บริษัท การค้าเชิงปริมาณ Jane Street ใช้ OCaml สำหรับการสร้างแบบจำลองทางการเงินและการดำเนินกลยุทธ์การซื้อขาย OCaml ยังใช้ใน FFTW เพื่อสร้างรหัส C บางตัวที่ใช้ในไลบรารี Liszt เป็นภาษาเฉพาะโดเมนที่พัฒนาขึ้นที่ Stanford และดำเนินการใน Scala ที่ใช้สำหรับการแก้ปัญหา PDE การเขียนโปรแกรมเชิงฟังก์ชั่นถูกนำมาใช้อย่างแน่นอนในอุตสาหกรรม (ไม่จำเป็นต้องอยู่ในสาขาวิทยาศาสตร์การคำนวณ); มันยังคงที่จะเห็นว่ามันจะถอดในวิทยาศาสตร์การคำนวณ


4
ฉันต้องการมีส่วนร่วมในการเพิ่มโปรและการควบคุม Pro :: ความยืดหยุ่นของรหัส:เนื่องจากทุกสิ่งเป็นฟังก์ชั่นคุณจึงสามารถเรียกใช้ฟังก์ชันนั้นโดยฟังก์ชั่นอื่นได้เสมอ มันมีพลังมหาศาล ข้อผิดพลาดในการอ่านโค้ด :: รหัสการเขียนโปรแกรมที่ใช้งานได้ยากต่อการอ่าน แม้กระทั่งสำหรับคนส่วนใหญ่ที่เขียนพวกเขา ตอนนี้ฉันต้องใช้เวลาสักพักกว่าจะเข้าใจรหัสเก่า ๆ ที่ฉันได้เขียนขึ้นเพื่อแก้ปัญหา PDE ทั่วไปด้วย B-splines ใน Mathematica 6 เดือนที่แล้ว ฉันมักจะดึงรหัสนั้นออกมาเมื่อฉันต้องการสร้างความกลัวให้กับเพื่อนร่วมงานบางคน ;-)
seb

4
นอกจากนี้เพียงคนเดียวที่ฉันจะเพิ่มคือการบริโภค Con :: หน่วยความจำ ต้องทำสำเนาจำนวนมากเพื่อกำจัดผลข้างเคียง
Matthew Emmett

1
@StefanSmith: (i) ฉันรู้ว่าบางครั้งมันถูกใช้ในการวิจัย (เช่น Maxima เป็น CAS ที่ใช้เสียงกระเพื่อม); นอกเหนือจากนั้นฉันไม่รู้ด้านบนของหัวของฉัน (ii) ไม่มีความคิด คำตอบส่วนใหญ่ของฉันขึ้นอยู่กับหลักฐานประวัติที่รวบรวมจากการสนทนาที่ฉันมีในช่วงไม่กี่ปีที่ผ่านมา
Geoff Oxberry

@seb ดูเหมือนว่าคุณกำลังอธิบายคุณสมบัติของภาษาที่ใช้งานได้เหมือนเสียงกระเพื่อมที่ไม่ได้ใช้งานได้ดีกับภาษาที่ใช้งานคล้ายกับ Haskell
มาร์คเอส

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

10

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

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

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


8

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

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

อีกสิ่งหนึ่งที่เจฟฟ์กล่าวถึงคือเวลาของนักพัฒนาซอฟต์แวร์นั้นสำคัญกว่าเวลาดำเนินการ ฉันทำงานให้กับ บริษัท ที่สร้าง SaaS ที่ใช้งานเชิงคำนวณอย่างเข้มข้นและเราทำการทดสอบประสิทธิภาพเบื้องต้นเมื่อเริ่มต้นโดยใช้ C ++ กับ Java เราพบว่า C ++ ให้เวลาการตัดผ่าน Java ประมาณ 50% (สำหรับเรขาคณิตเชิงคำนวณและตัวเลขส่วนใหญ่จะแตกต่างกันไปตามแอปพลิเคชัน) แต่เราไปกับ Java ต่อไปเพราะความสำคัญของเวลานักพัฒนาและหวังว่า การเพิ่มประสิทธิภาพและการปรับปรุงประสิทธิภาพฮาร์ดแวร์ในอนาคตจะช่วยให้เราสามารถทำการตลาดได้ ฉันสามารถพูดด้วยความมั่นใจที่เราเลือกเป็นอย่างอื่นเราจะไม่ยังคงอยู่ในธุรกิจ

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

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


8

เจฟฟ์ได้ให้ภาพรวมที่ดีของเหตุผลที่ฉันเพิ่มเล็กน้อยนอกเหนือจากการเน้นจุดหนึ่งของเขา: ระบบนิเวศ ไม่ว่าคุณจะสนับสนุนการเขียนโปรแกรมการทำงานหรือกระบวนทัศน์อื่น ๆ หนึ่งในคำถามสำคัญที่คุณต้องพูดถึงคือมีซอฟต์แวร์จำนวนมากที่ทุกคนสามารถสร้างขึ้นได้ตามที่คุณต้องเขียนใหม่ ตัวอย่างเช่น MPI, PETSc หรือ Trilinos สำหรับพีชคณิตเชิงเส้นหรือไลบรารีองค์ประกอบ จำกัด ใด ๆ - ทั้งหมดเขียนด้วย C หรือ C ++ มีความเฉื่อยจำนวนมากในระบบอาจไม่ใช่เพราะทุกคนคิดว่า C / C ++ เป็นภาษาที่ดีที่สุดในการเขียนซอฟต์แวร์การคำนวณ แต่เนื่องจากผู้คนจำนวนมากใช้เวลาหลายปีในการสร้างสิ่งที่มีประโยชน์ ผู้คนมากมาย

ฉันคิดว่าคนที่ใช้คอมพิวเตอร์ส่วนใหญ่จะยอมรับว่ามีคุณค่าเป็นอย่างมากในการลองภาษาโปรแกรมใหม่และประเมินความเหมาะสมของปัญหานี้ แต่มันจะเป็นช่วงเวลาที่ยากลำบากและเหงาเพราะคุณจะไม่สามารถสร้างผลลัพธ์ที่แข่งขันกับสิ่งที่คนอื่นกำลังทำอยู่ นอกจากนี้ยังอาจทำให้คุณมีชื่อเสียงในฐานะคนที่เริ่มก้าวต่อไปในกระบวนทัศน์การเขียนโปรแกรมที่แตกต่างกัน เฮ้ใช้เวลาแค่ C ++ ประมาณ 15 ปีในการเปลี่ยน Fortran!


6
และที่ดีที่สุดคือ C ++ เพียงครึ่งเดียวเท่านั้นที่จะแทนที่ Fortran ในพื้นที่นี้ เราเห็นรหัสใหม่ใน Fortran ตลอดเวลาและอีกหนึ่งมรดกที่จะบู๊ต!
Bill Barth

2
C ++ (ซึ่งแตกต่างจาก Fortran) นั้นซับซ้อนเกินกว่าที่จะเรียนรู้และใช้งาน รหัสทางวิทยาศาสตร์โอเพ่นซอร์สใหม่ยังคงถูกเขียนใน Fortran โดดเด่นในพื้นที่ของฉัน (Earth Sciences) เป็น PFlotran, SPECFEM3D, GeoFEM ฯลฯ เหมือนกันสำหรับรหัสใหม่เกือบทั้งหมดในวิทยาศาสตร์บรรยากาศ IMHO C ++ ไม่ได้แทนที่สิ่งที่ควรจะแทนที่ (C)
stali

1
คุณควรลอง Wolfgang ของ Fortran เป็นภาษาที่ยอดเยี่ยมเรียนรู้ / เขียนง่ายและความเร็วจะไม่ทำให้คุณผิดหวัง
อองเดรเซอร์ติก

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

4
@StefanSmith: ใช่ มันอาจเป็นความคิดที่ป้องกันได้ในการคำนวณทางวิทยาศาสตร์ (ที่ฉันจะยังคงยืนยันว่ามันล้าสมัยและไม่ก่อผล) แน่นอนว่ามันไม่สามารถป้องกันได้ตราบใดที่การศึกษาของนักเรียนเกี่ยวข้อง - เนื่องจากนักเรียนส่วนใหญ่ของเราออกจากสถาบันการศึกษาและในภาคอุตสาหกรรมแทบไม่มีใครใช้ Fortran
Wolfgang Bangerth

7

สรุปอย่างรวดเร็วคือ

  1. การคำนวณเชิงตัวเลขใช้ความไม่แน่นอน / ผลข้างเคียงเพื่อให้ได้ความเร็วสูงสุดและลดการจัดสรร (โครงสร้างการเขียนโปรแกรมการทำงานหลายอย่างมีข้อมูลที่ไม่เปลี่ยนรูป)
  2. การประเมิน Lazy นั้นค่อนข้างยากที่จะใช้กับรหัสตัวเลข
  3. ไม่ว่าคุณจะพัฒนาแพคเกจที่วางลงไปที่ระดับต่ำสุดสำหรับประสิทธิภาพการทำงานที่สำคัญจริงๆ (C / Fortran หรือตอนนี้ Julia) (ในสิ่งเหล่านี้คุณยังสามารถแก้ไขรหัสแอสเซมเบลอร์ได้ตามต้องการ) หรือคุณกำลังเขียนสคริปต์ ดังนั้นคุณมักจะสนใจเวลาในการพัฒนา (และคุณเลือก Julia / MATLAB / Python / R) ภาษาการใช้งานมักจะนั่งอยู่ตรงกลางแปลก ๆ ซึ่งมีประโยชน์ในสาขาอื่น แต่ไม่เป็นประโยชน์ที่นี่
  4. ส่วนใหญ่ของอัลกอริทึมตัวเลขสำหรับสมการเชิงอนุพันธ์, การเพิ่มประสิทธิภาพการพีชคณิตเชิงเส้นตัวเลข ฯลฯ จะถูกเขียน / พัฒนา / ได้รับการพิสูจน์ในแง่ของการบรรจบกันคือคุณมีประมาณและคุณต้องการที่จะได้รับ1} สไตล์ที่เป็นธรรมชาติในการใช้อัลกอริธึมเหล่านี้คือการวนซ้ำ (มีอัลกอริทึมบางอย่างที่เขียนซ้ำเช่นอัลกอริทึม multigrid บางอย่าง แต่สิ่งเหล่านี้หายากมาก)x n + 1xnxn+1

ข้อเท็จจริงเหล่านี้ร่วมกันทำให้การเขียนโปรแกรมใช้งานได้ดูเหมือนไม่จำเป็นสำหรับผู้ใช้ส่วนใหญ่


+1 แต่นอกเหนือจากข้อ 3: ฉันคิดว่าคุณสมบัติการใช้งานในภาษาระดับสูงมีประโยชน์มากและข้อดีของภาษาฟังก์ชันที่กล่าวถึงในคำตอบอื่น ๆ (เช่นการขนานอย่างง่าย) มักใช้กับสถานการณ์นี้
Szabolcs

3

ฉันคิดว่ามันน่าสนใจที่จะทราบว่าการใช้การเขียนโปรแกรมเชิงฟังก์ชันในวิทยาศาสตร์การคำนวณไม่ใช่เรื่องใหม่ ตัวอย่างเช่นกระดาษนี้จากปี 1990แสดงให้เห็นถึงวิธีการปรับปรุงประสิทธิภาพของโปรแกรมเชิงตัวเลขที่เขียนใน Lisp (อาจเป็นภาษาโปรแกรมการทำงานที่เก่าที่สุด) โดยใช้การประเมินบางส่วน งานนี้เป็นส่วนหนึ่งของห่วงโซ่เครื่องมือที่ใช้ในกระดาษปี 1992 โดยจีเจ Sussman (จากSICPยี่ห้อ) และ J ภูมิปัญญาซึ่งให้หลักฐานตัวเลขของพฤติกรรมวุ่นวายของระบบสุริยะ รายละเอียดเพิ่มเติมเกี่ยวกับฮาร์ดแวร์และซอฟต์แวร์ที่เกี่ยวข้องในการคำนวณที่สามารถพบได้ที่นี่


1

R เป็นภาษาที่ใช้งานได้และยังเป็นสถิติ (& ตอนนี้การเรียนรู้ของเครื่อง) และภาษาที่ 1 สำหรับสถิติ มันไม่ใช่ภาษา HPC: มันไม่ได้ใช้สำหรับ "การบีบอัดตัวเลข" แบบดั้งเดิมเช่นการจำลองทางฟิสิกส์เป็นต้น แต่สามารถใช้กับกลุ่มขนาดใหญ่ (เช่นผ่าน MPI) สำหรับการจำลองเชิงสถิติขนาดใหญ่ (MCMC) ของการเรียนรู้ของเครื่อง

Mathematica ยังเป็นภาษาที่ใช้งานได้ แต่โดเมนหลักคือการคำนวณเชิงสัญลักษณ์มากกว่าการคำนวณเชิงตัวเลข

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

ฉันจะไม่เรียก Scala เป็นภาษาที่ใช้งานได้ แต่เป็นลูกผสมระหว่างวัตถุและฟังก์ชัน คุณสามารถใช้แนวคิดการทำงานมากมายใน Scala Scala มีความสำคัญสำหรับการคำนวณแบบคลาวด์เนื่องจาก Spark ( https://spark.apache.org/ )

โปรดทราบว่า Fortran ที่ทันสมัยมีองค์ประกอบของการเขียนโปรแกรมฟังก์ชั่น: มันมีตัวชี้ความหมายที่เข้มงวด (ซึ่งแตกต่างจาก C) คุณสามารถมีฟังก์ชั่นบริสุทธิ์ (ไม่มีผลข้างเคียง) ฟังก์ชั่น (& ทำเครื่องหมายเป็นเช่นนี้) และคุณสามารถ มันยังมีการจัดทำดัชนีอัจฉริยะที่คุณสามารถระบุเงื่อนไขสำหรับดัชนีเมทริกซ์ นี่คือแบบสอบถามที่ชอบและมักจะพบในภาษาระดับสูงเช่น R ของ LINQ ใน C # หรือผ่านฟังก์ชันตัวกรองคำสั่งซื้อที่สูงขึ้นในภาษาที่ใช้งานได้ ดังนั้นฟอร์แทรนจึงไม่เลวเลยแม้แต่น้อยก็มีคุณสมบัติที่ทันสมัยบางอย่าง (เช่น co-arrays) ที่ไม่พบในหลายภาษา ในความเป็นจริงในรุ่นอนาคตของ Fortran ฉันอยากจะเห็นคุณสมบัติเพิ่มเติมที่เพิ่มเข้ามามากกว่า OO-features (ซึ่งตอนนี้เป็นกรณีปกติ) เพราะ OO ใน Fortran ค่อนข้างอึดอัดและน่าเกลียด


1

ข้อดีคือ "เครื่องมือ" ที่สร้างขึ้นในแต่ละภาษาที่ใช้งานได้: มันง่ายมากในการกรองข้อมูลมันง่ายมากในการวนซ้ำข้อมูลและมันง่ายกว่ามากในการหาวิธีแก้ปัญหาที่ชัดเจนและรัดกุม

ข้อเสียเพียงอย่างเดียวคือคุณต้องใช้ความคิดแบบใหม่นี้: อาจต้องใช้เวลาพอสมควรในการเรียนรู้สิ่งที่คุณต้องรู้ คนอื่น ๆ ในโดเมน SciComp ไม่ได้ใช้ภาษาเหล่านั้นจริงๆซึ่งหมายความว่าคุณไม่สามารถรับการสนับสนุนมากมาย :(

หากคุณมีความสนใจในภาษาเชิงวิทยาศาสตร์ฉันได้พัฒนาhttps://ac1235.github.ioหนึ่งฉบับ


1

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

ข้อเสีย : ไม่มีการสนับสนุนด้านภาษาใน C / C ++ / Fortran

อย่างน้อยใน C ++ คอนเวอร์ชันนี้จะหายไปเนื่องจาก C ++ 14/17 ได้เพิ่มสิ่งอำนวยความสะดวกที่มีประสิทธิภาพเพื่อรองรับการเขียนโปรแกรมที่ใช้งานได้ คุณอาจต้องเขียนไลบรารี่ / รหัสสนับสนุนด้วยตัวเอง แต่ภาษานั้นจะเป็นเพื่อนของคุณ เป็นตัวอย่างที่นี่เป็น (คำเตือน: ปลั๊ก) ห้องสมุดที่ไม่เปลี่ยนรูปอาร์เรย์หลายมิติใน C ++: https://github.com/jzrake/ndarray-v2

นอกจากนี้นี่คือลิงก์ไปยังหนังสือที่ดีเกี่ยวกับการเขียนโปรแกรมเชิงฟังก์ชันใน C ++ แม้ว่ามันจะไม่ได้เน้นที่การใช้งานทางวิทยาศาสตร์

นี่คือบทสรุปของสิ่งที่ฉันเชื่อว่าเป็นมืออาชีพ:

ข้อดี :

  • ความถูกต้อง
  • สามารถทำความเข้าใจได้
  • ประสิทธิภาพ

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

int main()
{
    auto state = initial_condition();

    while (should_continue(state))
    {
        state = advance(state);
        side_effects(state);
    }
    return 0;
}

การแก้สมการเชิงอนุพันธ์ย่อยบางส่วน (หรือ ODE) เหมาะสำหรับการโปรแกรมเชิงฟังก์ชัน คุณเพิ่งใช้ฟังก์ชั่น pure ( advance) กับโซลูชันปัจจุบันเพื่อสร้างฟังก์ชันถัดไป

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

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

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

ด้านล่างเป็นadvanceฟังก์ชั่นตัวอย่างซึ่งดัดแปลงมาจากรหัสปริมาณ จำกัด โดยใช้ndarray-v2แพ็คเกจ สังเกตto_sharedผู้ดำเนินการ - นี่คือคะแนนการประเมินที่ฉันพูดถึงก่อนหน้านี้

auto advance(const solution_state_t& state)
{
    auto dt = determine_time_step_size(state);
    auto du = state.u
    | divide(state.vertices | volume_from_vertices)
    | nd::map(recover_primitive)
    | extrapolate_boundary_on_axis(0)
    | nd::to_shared()
    | compute_intercell_flux(0)
    | nd::to_shared()
    | nd::difference_on_axis(0)
    | nd::multiply(-dt * mara::make_area(1.0));

    return solution_state_t {
        state.time + dt,
        state.iteration + 1,
        state.vertices,
        state.u + du | nd::to_shared() };
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.