(làm thế nào) viết mô phỏng chạy nhanh hơn?


16

Tôi đã bắt đầu sử dụng python làm ngôn ngữ lập trình để thực hiện tất cả các nhiệm vụ của mình trong CFD. Tôi có rất ít kinh nghiệm trong lập trình. Tôi đến từ nền tảng kỹ thuật cơ khí và đang theo đuổi giáo dục đại học về kỹ thuật hàng không vũ trụ.

đôi khi khía cạnh điện toán của CFD trở nên tẻ nhạt hơn là thao túng các phương trình hoặc làm toán.

Hướng dẫn chung làm cho chương trình của chúng tôi chạy nhanh hơn là gì? Các thủ thuật để làm những điều song song là gì? Làm thế nào để viết mã chạy nhanh hơn?

Tôi lấy tài nguyên ở đâu (dễ hiểu cho một giáo dân như tôi) trả lời các câu hỏi trên?



@ Dan, tôi không nghĩ vậy. Tôi đang yêu cầu 'bất kỳ' tài nguyên có thể nào sẽ giúp hiểu được một chiến thuật lập trình mới. Tôi không có bất kỳ yêu cầu cụ thể hoặc điều kiện áp đặt. Cụ thể hơn, tôi đang yêu cầu các tài nguyên sẽ giúp làm cho các mã thanh lịch hơn.
Subodh

Bạn đã sửa lỗi trên python hay bạn sẽ xem xét C ++? Trong trường hợp này tôi sẽ đề xuất hai điều: tìm hiểu C ++, tìm thư viện nguồn mở (trong trường hợp của tôi là OpenFOAM), không phát triển mọi thứ từ đầu, nhưng tìm hiểu, đào qua một đoạn mã nâng cao, tìm hiểu về khía cạnh của nó, thay đổi và thử nghiệm, tất cả được thúc đẩy với một mục đích cụ thể: trong trường hợp của bạn, ví dụ như mô phỏng khí động học.
tmaric

@ tomislav-maric, cảm ơn bạn rất nhiều. Tôi không phải là một "người pythonia" nghiêm khắc. Trong thực tế, là một người mới đến với lĩnh vực này, tôi nghĩ rằng tôi có rất nhiều lựa chọn có sẵn trước mặt tôi. Tôi cũng đang học OpenFOAM. Vì vậy, tôi đồng ý với quan điểm của bạn rằng một người nên bắt đầu làm việc trong một dự án và tìm hiểu thông qua đó (hoặc nói ngắn gọn là bẩn tay), đó chính xác là những gì tôi nên làm! Cảm ơn.
Subodh

@smj btw, tôi cũng đến từ một khu vực kỹ thuật cơ khí và bây giờ tôi là sinh viên tốt nghiệp ngành khoa học tính toán (kỹ thuật cơ khí KHÔNG chuẩn bị cho tôi về điều này) ... Nếu bạn đang làm việc với OF, hãy tìm kiếm cuốn sách C ++ danh sách trên stack stack, và bắt đầu học. Bạn cần 3 thứ: C ++, OpenFOAM và kiến ​​thức từ khoa học tính toán. OpenFOAM và khoa học tính toán, bạn có thể học theo cách dendritic: tìm một bài tập và hoàn thành nó, học theo những gì bạn cần. Có một cái gì đó hoàn thành sẽ thúc đẩy bạn. Đối với C ++: bắt đầu với C ++ Primer và tìm hiểu nó. Chúc may mắn! :)
tmaric

Câu trả lời:


19

Tôi sẽ cố gắng trả lời câu hỏi của bạn xem xét rằng bạn đang yêu cầu Python cụ thể. Tôi sẽ mô tả phương pháp riêng của tôi để giải quyết một vấn đề mô phỏng. Các chiến lược cho mô phỏng nhanh hơn được đưa ra trong mô tả này.

Đầu tiên, tôi tạo nguyên mẫu mô phỏng mới trong Python. Tất nhiên, tôi cố gắng sử dụng NumPySciPy nhiều nhất có thể. Trong khi NumPy cung cấp một kiểu dữ liệu mảng phù hợp cho các mô phỏng số, SciPy cung cấp một thói quen số rộng làm việc với các mảng NumPy.

Một khi các nguyên mẫu hoạt động ít nhiều, tôi cố gắng tìm hiểu phần nào của chương trình hoặc tập lệnh là nút cổ chai. Có những ứng cử viên điển hình cho điều đó:

  • Vòng lặp trong Python chậm. Rất chậm.
  • Vì Python sử dụng kiểu gõ vịt , các chức năng gọi có thể bị chậm.

Tôi sử dụng một chiến lược định hình đơn giản để tìm hiểu nơi dành tất cả thời gian chạy. Sử dụng shell IPython (mà tôi không thể khuyên dùng đủ), tôi chạy tập lệnh của mình với

%timeit script.py

Này "kỳ diệu lệnh" sẽ làm profiling (sử dụng timeit ) cho bạn và giới thiệu bạn một danh sách với thời gian một lần kịch bản của bạn đã chấm dứt. Sử dụng danh sách này để tìm ra nơi mã của bạn quá chậm.

Khi bạn đóng đinh các phần cần được tăng tốc, bạn có thể xem xét sử dụng các ngôn ngữ được biên dịch. Tôi sẽ chỉ ra hai giải pháp.

Đầu tiên, đó là ngôn ngữ Cython . Cython là một ngôn ngữ lập trình rất giống với Python (trên thực tế, mã Python cũng thường là mã Python hợp lệ); tuy nhiên, trình biên dịch Cython chuyển đổi các tệp Cython thành mã C, sau đó có thể được biên dịch thành một mô-đun có thể sử dụng được từ Python. Cython hiểu mảng NumPy. Có hai cách sử dụng Cython có thể giúp bạn: đầu tiên, bạn có thể giới thiệu các loại dữ liệu. Điều này sẽ tăng tốc các cuộc gọi chức năng. Ngoài ra, nếu bạn lặp qua các mảng, vòng lặp của bạn sẽ chạy nhanh hơn (thực tế, nếu bạn nhập cả biến giả và mảng, bạn sẽ có một vòng lặp C đơn giản!). Thứ hai, trong các thử nghiệm của tôi, ngay cả các tập lệnh chưa được chạy cũng chạy nhanh hơn một chút do thực tế là chúng được biên dịch thay vì diễn giải.

Ngôn ngữ được biên dịch khác sẽ hữu ích cho bạn là Fortran. Có nhiều cách khác nhau để sử dụng Fortran với Python ( f2py , fortwrap , Cython ). Đối với cá nhân tôi, f2py dường như là cách dễ nhất, tôi sẽ nhanh chóng mô tả những gì nó làm. f2py có thể biên dịch mã Fortran thành các mô-đun Python. Nó sẽ cho phép bạn sử dụng mảng NumPy làm biến đầu vào và đầu ra từ không gian Python. Trong không gian Fortran, đây sẽ là các mảng Fortran thông thường. Bạn có thể hoạt động trên những người ở tốc độ Fortran đầy đủ.

Cá nhân, tôi có xu hướng sử dụng Cython trong đó số lần gọi hàm là nút cổ chai. Đối với những thứ nặng về vòng lặp, tôi thích f2py hơn (có thể vì tôi có nền tảng Fortran mạnh mẽ).

Về ghi chú bổ sung trên Fortran: Fortran hiện đại đọc và viết rất giống với NumPy - cú pháp rất gần. Điều này giúp dễ dàng chuyển đổi mã NumPy sang mã Fortran.

Lưu ý rằng cả Cython và f2py đều hỗ trợ paralleism theo một cách nào đó. Đối với Cython, bạn sẽ tìm thấy trợ giúp ở đây , trong khi đối với Fortran, có các kỹ thuật tiêu chuẩn như OpenMP hoặc MPI. Hơn nữa, có cả trình bao bọc P ython cho MPI , quá. Cá nhân, tôi sử dụng mpi4py ở cấp độ Python cũng như OpenMP trong Fortran.

Hãy để tôi giới thiệu một chút về văn học: cuốn sách Python Scripting For Computational Science của H.-P. Langtangen là một tài nguyên tuyệt vời trên Python nói chung cũng như về các chiến lược để làm cho Python nhanh hơn một chút. Thật không may, AFAIR, nó không đề cập bất cứ điều gì trên Cython. Khi tôi tài nguyên thứ hai, bạn có thể nhìn vào các slide này . Chúng đưa ra ví dụ cho tất cả mọi thứ tôi đã đề cập trong bài đăng này (xem thêm mã và nguồn ở đây ). Có rất nhiều bộ slide tốt khác trên internet.

Nếu bạn có câu hỏi cụ thể hơn, tất cả chúng tôi rất sẵn lòng giúp đỡ!


1
Xem thêm các bài giảng về tối ưu hóa mã để biết tổng quan về trình biên dịch Python.
chối

7

Đối với CFD + Python có một giải pháp: http://pythonflu.wikidot.com/ Đây là các ràng buộc Python trên OpenFOAM (đã được đề cập trong các nhận xét cho các câu hỏi). Các ràng buộc này cho phép lập trình ở "cấp độ người giải quyết" (có những ví dụ trong đó trình giải OpenFOAM ban đầu được sao chép trong Python và chúng không chậm hơn bản gốc - các vòng lặp chậm được đề cập trong câu trả lời khác không phải là vấn đề ở đây vì "các vòng lặp bên trong" xảy ra ở đây trong C ++ - mã của OpenFOAM).

Ưu điểm của các ràng buộc này cũng là tất cả sự song song hóa trong OpenFOAM xảy ra bên dưới cấp độ bộ giải, do đó bạn không phải bận tâm đến nó (cũng như các thứ khác mà lõi OpenFOAM quan tâm: đầu vào / đầu ra, bộ giải tuyến tính, phân biệt toán tử)

Vì vậy, nếu bạn chỉ muốn viết một bộ giải mới và không thêm các tính năng mới vào lõi OF (điều kiện biên, bộ giải tuyến tính, v.v.) thì PythonFlu có thể đủ cho bạn và bạn có thể tránh C ++ (có khả năng học tập cao hơn nhiều so với Con trăn

PS: ban đầu muốn thêm điều này như một bình luận vào cuộc thảo luận về câu hỏi ban đầu, nhưng danh tiếng của tôi không cho phép tôi điều này


Xin chào Bernhard! Chào mừng đến với scicomp! :)
tmaric
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.