Saya ingin mengembangkan perangkat lunak komputasi paralel ilmiah dari awal. Saya ingin beberapa pemikiran tentang bahasa mana untuk memulai. Program ini melibatkan membaca / menulis data ke file txt dan melakukan perhitungan berat secara paralel, dengan banyak faktorisasi LU dan penggunaan pemecah linier yang jarang. Solusi kandidat yang saya pikirkan adalah Fortran 2003/2008 dengan OpenMP atau co-array, C ++ dengan openmp cilk + atau TBB, python. Saran lainnya, yang terdokumentasi, dipersilakan! Saya tahu betul C, Fortran dan Jawa (dalam urutan itu). Saya telah melakukan beberapa scripting dengan python tetapi hal-hal dasar.
Saya tahu fortran sangat cepat, tetapi sulit dipertahankan dan diparalelkan. C ++ dikatakan lambat kecuali jika Anda menggunakan perpustakaan eksternal dll. Python saya suka, tetapi apakah realistis untuk menulis skala penuh, perangkat lunak tingkat industri?
Perangkat lunak ini harus mampu menangani data dalam jumlah besar dan efektif dengan perhitungan ilmiah. Kinerja adalah esensi.
Untuk latar belakang, saya sudah memiliki perangkat lunak yang berfungsi ditulis dalam Fortran. Banyak orang terlibat dalam pengembangan selama bertahun-tahun dan kodenya benar-benar kotor. Mempertahankan dan memparalelkan kode telah membuktikan mimpi buruk dan saya sedang memikirkan alternatif.
Petros
Jawaban:
Biarkan saya mencoba dan menjabarkan persyaratan Anda:
Dari daftar ini, saya akan mempertimbangkan bahasa-bahasa berikut:
C, C ++, Fortran, Python, MATLAB, Java
Julia adalah bahasa baru yang menjanjikan, tetapi komunitas masih membentuk sekitarnya dan belum digunakan dalam kode baru utama.
Membaca / menulis data teks
Ini mudah dilakukan dengan benar dalam bahasa pemrograman apa pun. Pastikan Anda melindungi dan menyatukan akses I / O Anda dengan tepat, dan Anda akan mendapatkan kinerja yang baik dari salah satu bahasa yang harus Anda pertimbangkan. Hindari streaming objek di C ++ kecuali Anda tahu cara menggunakannya secara performant.
Antarmuka / kemampuan yang kuat untuk faktorisasi LU
Jika Anda melakukan padat faktorisasi LU, Anda akan ingin menggunakan LAPACK, atau ScaLAPACK / Elemental untuk fungsi paralel. LAPACK dan ScaLAPACK ditulis dalam Fortran, Elemental ditulis dalam C ++. Ketiga perpustakaan tersebut berkinerja baik, didukung dan didokumentasikan dengan baik. Anda dapat antarmuka ke dalamnya dari salah satu bahasa yang harus Anda pertimbangkan.
Pemecah linier yang jarang
Solver linier jarang yang tersedia secara bebas hampir semuanya tersedia melalui PETSc , ditulis dalam C, yang didokumentasikan dan didukung dengan baik. Anda dapat antarmuka ke dalam PETSc dari salah satu bahasa yang harus Anda pertimbangkan.
Kinerja dan skalabilitas untuk data besar
Satu-satunya paradigma pemrograman paralel yang Anda sebutkan adalah berbasis memori bersama, yang berarti Anda tidak mempertimbangkan pendekatan komputasi distribusi memori berbasis MPI (message-passing). Dalam pengalaman saya, jauh lebih mudah untuk menulis kode yang skala jauh melampaui selusin inti menggunakan solusi memori terdistribusi. Hampir semua "cluster" Universitas berbasis MPI hari ini, mesin memori bersama yang besar harganya mahal, dan jarang terjadi. Anda harus mempertimbangkan MPI untuk pendekatan Anda, tetapi saran saya akan berlaku terlepas dari paradigma pemrograman yang Anda pilih.
Sehubungan dengan kinerja on-node, jika Anda menulis rutinitas numerik sendiri, paling mudah untuk mendapatkan kinerja serial yang baik di Fortran. Jika Anda memiliki sedikit pengalaman dalam C, C ++, atau Python, Anda bisa mendapatkan kinerja yang sangat sebanding (C dan C ++ mati-bahkan dengan Fortran, Python dan MATLAB memiliki sekitar 25% waktu overhead tanpa banyak usaha). MATLAB melakukan ini melalui kompiler JIT dan ekspresifitas aljabar linier yang sangat baik. Anda mungkin perlu menggunakan kernel Cython, numpy, numexpr, atau embed numerik untuk mendapatkan kinerja yang diklaim dari Python. Saya tidak dapat mengomentari kinerja Java, karena saya tidak tahu bahasanya dengan baik, tetapi saya curiga bahasa ini tidak jauh dari Python jika ditulis oleh seorang ahli.
Catatan tentang antarmuka
Saya harap saya telah meyakinkan Anda bahwa Anda akan dapat melakukan semua yang Anda inginkan dalam bahasa pemrograman yang Anda pertimbangkan. Jika Anda menggunakan Java, antarmuka C akan sedikit menantang. Python memiliki dukungan antarmuka C dan Fortran yang sangat baik melalui ctypes, Cython, dan f2py. LAPACK sudah dibungkus dan tersedia melalui scipy. MATLAB memiliki semua fungsionalitas yang Anda butuhkan di pustaka aslinya, tetapi tidak mudah diskalakan atau sangat mudah dijalankan pada cluster. Java dapat mendukung antarmuka C dan Fortran dengan JNI , tetapi tidak umum ditemukan pada cluster dan perangkat lunak paralel untuk komputasi ilmiah.
Maintabilitas
Banyak dari ini akan turun ke selera pribadi, tetapi konsensus umum tentang rawatan adalah bahwa Anda ingin meminimalkan jumlah baris kode dalam perangkat lunak Anda, menulis kode modular dengan antarmuka yang terdefinisi dengan baik, dan untuk perangkat lunak komputasi, menyediakan tes yang memverifikasi kebenaran dan fungsionalitas implementasi.
Rekomendasi
Saya pribadi telah memiliki banyak keberuntungan dengan Python dan saya merekomendasikannya untuk banyak proyek komputasi. Saya pikir Anda harus sangat mempertimbangkannya untuk proyek Anda. Python dan MATLAB mungkin adalah bahasa yang paling ekspresif yang tersedia untuk komputasi ilmiah. Anda dapat dengan mudah antarmuka Python ke bahasa pemrograman lain, Anda dapat menggunakan f2py untuk membungkus implementasi Fortran Anda saat ini dan menulis ulang sepotong demi sepotong bagian mana pun yang Anda inginkan dalam Python sambil memverifikasi bahwa Anda mempertahankan fungsionalitas. Pada saat ini, saya akan merekomendasikan kombinasi implementasi Python 2.7 resmi dengan scipy . Anda dapat dengan mudah memulai dengan tumpukan ini dari Enthought Python Distribution yang tersedia secara bebas .
Anda juga bisa melakukan sebagian besar ini dalam C, C ++, atau Fortran. C dan C ++ adalah bahasa yang sangat menarik untuk pengembang profesional dengan banyak pengalaman, tetapi sering membuat pengembang baru dan dalam hal ini mungkin bukan ide yang bagus untuk kode yang lebih akademis. Fortran dan MATLAB populer dalam perhitungan akademis, tetapi lemah pada struktur data canggih dan penawaran ekspresif Python (pikirkan objek dict Python, misalnya).
Pertanyaan-pertanyaan Terkait:
sumber
Selain jawaban Aron yang sangat komprehensif, saya akan melihat berbagai utas tentang scicomp.stackexchange yang membahas pertanyaan tentang bahasa pemrograman mana yang akan diambil - baik mengenai kecepatan program maupun pertanyaan tentang seberapa mudah atau sulitnya itu untuk menulis dan memelihara perangkat lunak dalam bahasa-bahasa ini.
Yang mengatakan, selain apa yang telah ditulis di sana, izinkan saya membuat beberapa pengamatan:
(i) Anda memasukkan Fortran co-array dalam daftar Anda. Setahu saya, jumlah kompiler yang benar-benar mendukungnya sangat kecil - dan saya, sebenarnya, nol. Kompiler Fortran yang paling banyak tersedia adalah GNU gfortran, dan sementara sumber pengembangan saat ini menguraikan subset dari co-array, saya percaya bahwa itu sebenarnya tidak mendukung semua itu (yaitu, ia menerima sintaks tetapi tidak mengimplementasikan semantik) . Ini tentu saja merupakan pengamatan umum tentang standar Fortran yang lebih baru: bahwa kelambatan yang digunakan penyusun sebenarnya mendukung standar baru diukur dalam beberapa tahun - penyusun hanya menerapkan sepenuhnya Fortran 2003 dalam beberapa tahun terakhir, dan hanya sebagian mendukung Fortran 2008. Ini seharusnya tidak menghentikan Anda dari menggunakannya jika Anda memiliki kompiler yang mendukung apa yang Anda gunakan,
(ii) Hal yang sama juga berlaku untuk C ++ / Cilk +: Ya, Intel mengembangkan ini pada cabang GCC tetapi tidak tersedia di rilis GCC mana pun dan, sepertinya, tidak akan untuk sementara waktu. Anda bisa berharap untuk mengambil 2-3 tahun lagi setidaknya sampai Anda akan menemukan Cilk + dengan versi GCC diinstal pada mesin linux yang khas.
(iii) C ++ / TBB adalah cerita yang berbeda: TBB telah ada untuk sementara waktu, memiliki antarmuka yang sangat stabil dan dapat dikompilasi dengan sebagian besar kompiler C ++ yang telah ada selama beberapa tahun terakhir (di linux dan juga di windows) . Kami telah menggunakannya dalam kesepakatan. Saya selama beberapa tahun sudah dengan hasil yang baik. Ada juga buku yang sangat bagus.
(iv) Saya memiliki pendapat sendiri tentang OpenMP, yaitu bahwa ini merupakan solusi dalam mencari masalah. Ini bekerja dengan baik untuk memparalelkan loop dalam yang mungkin menarik jika Anda memiliki struktur data yang sangat teratur. Tetapi jarang apa yang ingin Anda lakukan jika Anda perlu memparalelkan sesuatu - karena apa yang sebenarnya ingin Anda lakukan adalah memparalelkan loop luar . Dan untuk itu, solusi seperti TBB adalah solusi yang jauh lebih baik karena mereka menggunakan mekanisme bahasa pemrograman daripada mencoba menggambarkan apa yang terjadi di luar bahasa (melalui #pragmas) dan sedemikian rupa sehingga Anda tidak memiliki akses ke ulir thread , indikator status hasil, dll, dari dalam program Anda.
(v) Jika Anda eksperimental, Anda mungkin juga melihat bahasa pemrograman baru yang dirancang untuk pemrograman paralel dan, khususnya, untuk tugas-tugas seperti yang Anda jelaskan. Pada dasarnya ada dua yang akan saya lihat: X10 dan Chapel . Saya telah melihat tutorial yang bagus tentang Chapel, dan tampaknya dirancang dengan baik, meskipun keduanya tentu saja hari ini adalah solusi picik juga.
sumber
Secara umum, jika Anda benar-benar serius tentang proyek perangkat lunak ini, saya sarankan menulis ulang lengkap dalam bahasa apa pun yang Anda sendiri merasa paling nyaman dengannya. Sepertinya Anda akan melakukan pekerjaan sendiri, dan karena itu Anda akan mendapatkan hasil terbaik dalam bahasa yang paling Anda sukai di rumah.
Lebih khusus lagi, mengenai paralelisme, saya mendorong Anda untuk mencoba berpikir sedikit di luar kebiasaan. OpenMP memiliki kelebihan, tetapi terjebak dalam pola pikir mengambil kode sekuensial dan menampar paralelisme di sana-sini. Hal yang sama berlaku untuk Intels TBB.
Cilk jelas merupakan langkah ke arah yang benar, yaitu memaksa Anda untuk memikirkan kembali masalah / solusi Anda dalam pengaturan paralel yang inheren. Namun, yang saya tidak suka tentang itu adalah bahwa itu adalah bahasa lain . Juga, karena hanya dapat secara kasar menyimpulkan hubungan antara tugas paralel, penjadwal bisa sangat konservatif dan mungkin tidak skala dengan baik untuk masalah tertentu.
Namun, kabar baiknya adalah, bahwa, sekali lagi, jika Anda serius tentang implementasi Anda, Anda dapat melakukan apa yang dilakukan Cilk, misalnya menulis ulang masalah Anda sebagai serangkaian tugas yang saling tergantung dan mendistribusikannya ke sejumlah prosesor / core, semuanya Anda gunakan menggunakan pthreads atau menyalahgunakan OpenMP untuk memunculkan proses. Contoh yang bagus tentang bagaimana hal ini dapat dilakukan adalah penjadwal QUARK yang digunakan di perpustakaan PLASMA . Perbandingan bagus antara kinerjanya vs Cilk diberikan di sini .
sumber
pthreads-win32
atau dalamcygwin
proyek.Ada sedikit diskusi tentang coarray fortran di komentar di atas. Pada saat ini, dan setahu saya, dukungan coarray dalam kompiler kira-kira sebagai berikut:
Secara umum, saya akan berhati-hati jika memulai kode berbasis coarray. Sintaksnya sederhana dan jauh lebih nyaman daripada Fortran / C / C ++ dengan MPI, tapi kemudian, hanya saja tidak memiliki fitur lengkap. Misalnya, MPI mendukung banyak operasi pengurangan, dll. Yang mungkin sangat nyaman bagi Anda. Itu akan sangat tergantung pada kebutuhan Anda akan banyak komunikasi. Jika Anda ingin contoh, beri tahu saya dan saya dapat memberikan beberapa kepada Anda, jika saya dapat menggali file.
sumber
Lihatlah Spark itu kerangka kerja terdistribusi untuk komputasi dalam memori yang mengambil keuntungan dari pemrograman fungsional. Struktur sebuah program di Spark sangat berbeda jika dibandingkan dengan MPI, pada dasarnya Anda menulis kode seperti untuk komputer tunggal, yang secara otomatis didistribusikan sebagai fungsi ke data yang berada di memori. Ini mendukung Scala, Java dan Python.
Regresi Logistik (scala):
Ada ekstensi untuk disebut MLib (Perpustakaan Pembelajaran Mesin) yang menggunakan perpustakaan Fortran untuk beberapa perhitungan tingkat rendah (untuk Python saya kira numpy digunakan). Jadi, idenya sederhana, berkonsentrasilah pada algoritma Anda dan tinggalkan optimisasi ke level yang lebih rendah (urutan pemrosesan, distribusi data, dll.).
sumber