ComBioLaw.De » Blog » เขียนโปรแกรม » เพิ่มความเร็วให้ Python ตอน 3 : f2py, numpy
เพิ่มความเร็วให้ Python ตอน 3 : f2py, numpy
สาเหตุที่โปรแกรมที่เขียนด้วย Pyrex ทำงานช้าก็เพราะจำนวนเชิงซ้อนครับ และจำนวนเชิงซ้อนเป็นสิ่งที่จำเป็นมากมายใน simulation เกี่ยวกับการส่งสัญญาณที่ผมพัฒนาอยู่ ที่จำนวนเชิงซ้อนทำให้โปรแกรมทำงานช้าก็เพราะว่า จำนวนเชิงซ้อนไม่สามารถถูกแปลงเป็นตัวแปรภาษา C โดยผ่าน cdef ได้ ความเร็วการคำนวนเชิงซ้อนใน Pyrex จึงไม่ต่างจากการคำนวนจำนวนเชิงซ้อนใน Python มากนัก ผมก็เลยต้องหาวิธีเพิ่มความเร็วให้ Python วิธีอื่น ๆ เพิ่มเติม เดิมทีนั้นผมรู้จัก f2py อยู่แล้ว f2py เป็นเครื่องมือที่ใช้คอมไพล์ Subroutine + Function ภาษา FORTRAN ให้เป็น library สำหรับ Python แต่... |
|
|
ผมไม่ชอบใช้ f2py เท่าใดนักเนื่องเพราะ
ด้วยปัญหาต่าง ๆ เหล่านี้ ทำให้ผมต้องหาทางออกเพิ่มเติม ซึ่งก็ไปเจอของดีเข้า มันคือ numpy จริง ๆ แล้วแนวคิดของ numpy ไม่ใหม่ครับ มันก็คือ Numeric Python กับ numarray ที่เขียนใหม่ ซึ่งสองโมดูลที่ว่า ถูกสร้างขึ้นเพื่อให้ Python สามารถใช้แทน MATLAB ได้ แต่ด้วยปัญหาบางอย่าง เลยต้องพัฒนาใหม่จนกลายมาเป็น numpy สิ่งที่ผมคิดว่าพิเศษมาก ๆ ใน numpy นอกจากการใช้งานที่ง่ายเหมือ MATLAB แล้ว คือ ความเร็วที่สูงมาก เทียบเท่าโปรแกรมที่เขียนด้วยภาษา C (อีกแล้ว) แต่เราจะได้ความเร็วดังกล่าวก็ต่อเมื่อ เราใช้ operation ระหว่าง array โดยตรงเท่านั้น ไม่ใช่ operation ระหว่างสมาชิกใน array โดยผ่าน for loop ยกตัวอย่างเช่น
from numpy import * a = arange(0.0,20.0,0.01, dtype=complex64) + 1.0j*arange(0.0,20.0,0.01, dtype=complex64) b = a[-1::-1] c = a+b # จะเร็วกว่าการใช้ for loop ประมาณ 50 เท่า for i in range(len(a)): c[i] = a[i]+b[i]plain code ผมคิดว่าการใช้ operation ระหว่าง array นั้น แม้จะคลอบคลุมการใช้งานไม่ได้ทั้งหมด แต่ก็คลอบคลุมได้กว่า 80% เลยทีเดียว ในตัว numpy เองก็มีโมดูลต่าง ๆ ให้เลือกใช้งานมากมาย สามารถดูตัวอย่างได้ที่ Numpy Example List ปัญหาอย่างหนึ่งที่ผมแก้ไม่ตกคือ simulation วงจรที่มี feed back ซึ่งวงจรเหล่านี้คือวงจรที่ข้อมูลขาออกมีผลต่อข้อมูลขาเข้า หรือ recursive นั่นเองครับ ซึ่งการ simulation วงจรเหล่านี้จำเป็นอย่างยิ่งที่ต้องใช้ for loop (คนใช้ Simulink อาจบอกว่าไม่จำเป็น) หรือหากไม่ใช้ for loop ก็ต้องนั่ง คำนวนโดยใช้ Laplace หรือ FFT กันจนปวดหัว การใช้ for loop ทำให้ simulation ช้าลงประมาณ 50 เท่า ซึ่งเป็นตัวเลขที่ไม่น่าพอใจเอาเสียเลย ผมเลยจำเป็นต้องกลับไปใช้ f2py ในกรณีที่ต้องใช้ for loop และเพื่อไม่ให้ปัญหาที่ผมเคยพบใน f2py กลับมาหาผมอีก ผมเลยต้องตั้งเงื่อนไขส่วนตัวในการใช้งาน f2py เพิ่มเติมดังนี้ครับ
python p2p.py # แยกคอมไพล์ไฟล์ .f python p2p.py in_one modulename #รวมไฟล์ .f ทั้งหมดเป็นไฟล์เดียว แล้วคอมไพล์เป็นโมดูลชื่อ modulenameplain code ส่วนการเรียกใช้เป็น module สามารถใช้งานได้ดังนี้ครับ
import p2p p2p.p2p() # เหมือนคำสั่ง python p2p.py p2p.p2p("modulename") # เหมือนคำสั่ง python p2p.py in_one modulenameplain code ซึ่งใน simulation ที่ผมพัฒนาอยู่นั้น ผมใช้เทคนิคทุกอย่างที่ผมได้เขียนมาครับ ไม่ว่าจะเป็น Pyrex, Psyco, numpy, f2py ส่วนผู้ร่วมงานของผมคนอื่น ๆ ใช้ FORTRAN 77 กัน แต่การทำงานร่วมกันก็ไม่เคยเกิดปัญหาใด ๆ หรือหากจะมีใครต้องการจะใช้ภาษา C ก็ไม่ใช่เรื่องยากครับ ที่จะทำงานร่วมกัน เพราะเรายังมี SWIG ให้ใช้งานอยู่ ผมถือว่านี่เป็นเสน่ห์อย่างหนึ่งของ OpenSource และ Python ครับ ที่ทุกคนสามารถทำงานร่วมกันได้ โดยที่มีความถนัดไม่เหมือนกัน ใช้เครื่องมือไม่เหมือนกัน |
|
04 Mar 07 | by | tags เขียนโปรแกรม Python f2py numpy
หลังจากที่ผมเขียนเรื่อง 