(วิธี) เขียนการจำลองที่ทำงานเร็วขึ้น?


16

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

บางครั้งด้านการคำนวณของ CFD นั้นน่าเบื่อกว่าจัดการสมการหรือทำคณิตศาสตร์

แนวทางทั่วไปที่ทำให้โปรแกรมของเราทำงานเร็วขึ้นคืออะไร ลูกเล่นอะไรที่ต้องทำสิ่งต่าง ๆ อย่างขนานกัน? จะเขียนรหัสที่ทำงานได้เร็วขึ้นได้อย่างไร

ฉันจะหาแหล่งข้อมูลได้ที่ไหน (เข้าใจได้ง่ายสำหรับคนธรรมดาอย่างฉัน) ที่ตอบคำถามข้างต้น



@ แดนฉันไม่คิดอย่างนั้น ฉันขอทรัพยากรที่เป็นไปได้ 'ใด ๆ ' ที่จะช่วยให้เข้าใจกลยุทธ์การเขียนโปรแกรมใหม่ ฉันไม่มีข้อกำหนดหรือเงื่อนไขเฉพาะใด ๆ โดยเฉพาะอย่างยิ่งฉันขอทรัพยากรที่จะช่วยทำให้รหัสสวยงามยิ่งขึ้น
Subodh

คุณได้รับการแก้ไขใน python หรือคุณจะพิจารณา C ++ หรือไม่ ในกรณีนี้ฉันขอแนะนำสองสิ่ง: เรียนรู้ C ++, หา open source library (ในกรณีของฉัน OpenFOAM), อย่าพัฒนาสิ่งต่าง ๆ ตั้งแต่เริ่มเรียน แต่เรียนรู้ขุดผ่านโค้ดขั้นสูงเรียนรู้เกี่ยวกับแง่มุมการเปลี่ยนแปลงและ การทดลองทั้งหมดขับเคลื่อนด้วยจุดประสงค์เฉพาะ: ในกรณีของคุณเช่นการจำลองตามหลักอากาศพลศาสตร์
tmaric

@ tomislav-maric ขอบคุณมาก ฉันไม่ใช่ 'pythonian' ที่เข้มงวด ในความเป็นจริงการเป็นผู้มาใหม่ในสนามฉันคิดว่าฉันมีตัวเลือกมากมายอยู่ข้างหน้าฉัน ฉันกำลังเรียนรู้ OpenFOAM ด้วย ดังนั้นฉันจึงเห็นด้วยกับมุมมองของคุณว่าควรเริ่มทำงานในโครงการและเรียนรู้ผ่าน (หรือในระยะสั้นรับมือสกปรก) ซึ่งเป็นสิ่งที่ฉันควรทำ! ขอบคุณ
Subodh

@smj btw ฉันมาจาก bacground วิศวกรรมเครื่องกลเช่นกันและตอนนี้ฉันเป็นนักศึกษาระดับบัณฑิตศึกษาในสาขาวิทยาศาสตร์คอมพิวเตอร์ (mech. วิศวกรรมไม่ได้เตรียมฉันไว้สำหรับเรื่องนี้) ... หากคุณกำลังทำงานกับ OF ให้ค้นหาหนังสือ C ++ รายการล้นสแต็คและเริ่มเรียนรู้ คุณต้องการ 3 สิ่ง: C ++, OpenFOAM และความรู้จากวิทยาศาสตร์การคำนวณ OpenFOAM และวิทยาศาสตร์การคำนวณคุณสามารถเรียนรู้ด้วยวิธี dendritic: ค้นหางานที่มอบหมายและทำมันให้สำเร็จเรียนรู้สิ่งที่คุณต้องการ การมีบางสิ่งบางอย่างเสร็จจะช่วยกระตุ้นคุณ สำหรับ C ++: เริ่มต้นด้วย C ++ Primer และเรียนรู้มัน โชคดี! :)
tmaric

คำตอบ:


19

ฉันจะพยายามตอบคำถามของคุณโดยพิจารณาว่าคุณกำลังขอ Python โดยเฉพาะ ฉันจะอธิบายวิธีการจัดการปัญหาการจำลองของฉันเอง กลยุทธ์สำหรับการจำลองที่เร็วกว่านั้นมีให้ในคำอธิบายนี้

ก่อนอื่นฉันสร้างแบบจำลองใหม่ใน Python แน่นอนฉันพยายามใช้ประโยชน์จากNumPyและSciPyให้มากที่สุดเท่าที่จะทำได้ ในขณะที่ NumPy มีประเภทข้อมูลอาร์เรย์ที่เหมาะสมสำหรับการจำลองเชิงตัวเลข SciPy เสนอรูทีนตัวเลขที่กว้างซึ่งทำงานกับ NumPy arrays

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

  • การวนซ้ำใน Python ช้า ช้ามาก.
  • เนื่องจาก Python ใช้การพิมพ์เป็ดฟังก์ชันการโทรอาจช้า

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

%timeit script.py

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

เมื่อคุณตอกย้ำส่วนที่ต้องเร่งคุณอาจพิจารณาใช้ภาษาที่รวบรวม ฉันจะชี้ไปที่วิธีแก้ปัญหาสองข้อ

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

ภาษาที่รวบรวมอื่น ๆ ที่จะเป็นประโยชน์สำหรับคุณคือ Fortran มีวิธีต่าง ๆ ในการใช้ Fortran กับ Python ( f2py , fortwrap , Cython ) สำหรับฉัน f2py ส่วนตัวดูเหมือนจะเป็นวิธีที่ง่ายที่สุดฉันจะอธิบายสิ่งที่มันทำ f2py สามารถรวบรวมรหัส Fortran ไปยังโมดูล Python มันจะช่วยให้คุณใช้อาร์เรย์ NumPy เป็นตัวแปรอินพุตและเอาต์พุตจากพื้นที่ Python ในพื้นที่ของ Fortran สิ่งเหล่านี้จะเป็นอาร์เรย์ของ Fortran ทั่วไป คุณสามารถใช้งานได้กับความเร็ว Fortran

โดยส่วนตัวแล้วฉันมักจะใช้ Cython ที่จำนวนการเรียกใช้ฟังก์ชันเป็นคอขวด สำหรับสิ่งที่มีน้ำหนักมากฉันชอบ f2py (อาจเป็นเพราะฉันมีพื้นหลัง Fortran ที่แข็งแกร่ง)

ในหมายเหตุเพิ่มเติมเกี่ยวกับ Fortran: Fortran ที่ทันสมัยอ่านและเขียนคล้ายกับ NumPy - ไวยากรณ์อยู่ใกล้มาก สิ่งนี้ทำให้ง่ายต่อการแปลงรหัส NumPy เป็นรหัส Fortran

โปรดทราบว่าทั้ง Cython และ f2py สนับสนุนอัมพาตในบางประการ สำหรับ Cython คุณจะพบความช่วยเหลือได้ที่นี่ส่วน Fortran มีเทคนิคมาตรฐานเช่นOpenMPหรือ MPI นอกจากนี้ยังมีแผ่นปิด P ython สำหรับ MPIอีกด้วย โดยส่วนตัวแล้วฉันใช้ mpi4py ในระดับ Python และ OpenMP ใน Fortran

ให้ฉันแนะนำวรรณกรรมสักหน่อย: หนังสือPython Scripting For Computational Scienceโดย H.-P. Langtangen เป็นทรัพยากรที่ยอดเยี่ยมสำหรับ Python โดยทั่วไปเช่นเดียวกับกลยุทธ์ที่ทำให้ Python เร็วขึ้นเล็กน้อย น่าเสียดายที่ AFAIR ไม่ได้พูดถึงสิ่งใดใน Cython เป็นทรัพยากรที่สองผมคุณอาจดูภาพนิ่งเหล่านี้ เหล่านี้เป็นตัวอย่างสำหรับทุกสิ่งที่ฉันพูดถึงในโพสต์นี้ (ดูรหัสและแหล่งที่นี่ ) มีภาพนิ่งชุดอื่น ๆ อีกมากมายที่ดีบนอินเทอร์เน็ต

หากคุณมีคำถามเพิ่มเติมเรายินดีให้ความช่วยเหลือ!


1
ดูเพิ่มเติมที่scipy-lectures เกี่ยวกับการปรับโค้ดให้เหมาะสมสำหรับภาพรวมของโปรไฟล์ Python
เดนิส

7

สำหรับ CFD + Python มีวิธีแก้ไข: http://pythonflu.wikidot.com/นี่คือ Python-bindings ด้านบนของ OpenFOAM (ซึ่งถูกกล่าวถึงในข้อคิดเห็นของคำถาม) การเชื่อมโยงเหล่านี้อนุญาตให้ตั้งโปรแกรมใน "ระดับตัวแก้ปัญหา" (มีตัวอย่างที่ตัวแก้แบบ OpenFOAM ดั้งเดิมถูกจำลองแบบใน Python และไม่ช้ากว่าต้นฉบับ - การวนรอบช้าที่กล่าวถึงในคำตอบอื่นไม่ใช่ปัญหาที่เกิดขึ้นในขณะนี้ ใน C ++ - รหัสของ OpenFOAM)

ข้อดีของการรวมเหล่านี้คือการขนานทั้งหมดใน OpenFOAM เกิดขึ้นภายใต้ระดับ solver ดังนั้นคุณไม่ต้องกังวลกับมัน (รวมถึงสิ่งอื่น ๆ ที่ OpenFOAM-core ดูแล: input / output, การแก้ปัญหาเชิงเส้น, discretization ประกอบ)

ดังนั้นหากคุณต้องการเขียนตัวแก้ปัญหาใหม่และไม่เพิ่มคุณสมบัติใหม่ให้กับ OF-core (เงื่อนไขขอบเขตตัวแก้ปัญหาเชิงเส้น ฯลฯ ) PythonFlu อาจเพียงพอสำหรับคุณและคุณสามารถหลีกเลี่ยง C ++ (ซึ่งมีวิธีการเรียนรู้ที่สูงกว่า งูใหญ่)

PS: เดิมต้องการเพิ่มสิ่งนี้เป็นความคิดเห็นในการอภิปรายของคำถามเดิม แต่ชื่อเสียงของฉันไม่อนุญาตให้ฉันนี้


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