Bahasa C ++ menyediakan pemrograman generik dan metaprogramming melalui template. Teknik-teknik ini telah menemukan jalan mereka ke banyak paket komputasi ilmiah skala besar (misalnya, MPQC , LAMMPS , CGAL , Trilinos ). Tetapi apa yang sebenarnya mereka sumbangkan dalam komputasi ilmiah dalam nilai yang melampaui bahasa non-generik, non-meta seperti C atau Fortran dalam hal waktu pengembangan keseluruhan dan kegunaan untuk efisiensi yang sama atau memadai?
Mengingat tugas komputasi ilmiah, apakah pemrograman generik dan meta melalui templat C ++ menunjukkan peningkatan produktivitas, ekspresivitas, atau kegunaan yang diukur dengan tolok ukur yang dipahami dengan baik (garis kode, upaya orang, dll ...)? Sejalan dengan itu, risiko apa yang terkait dengan penggunaan templat C ++ untuk generik dan pemrograman?
sumber
Jawaban:
Saya pikir pada umumnya, metaprogramming template telah ditemukan tidak dapat digunakan dalam praktiknya - ini mengkompilasi terlalu lambat, dan pesan kesalahan yang kita dapatkan hanya mustahil untuk diuraikan. Hambatan masuk untuk pendatang baru juga terlalu tinggi saat menggunakan metaprogramming.
Tentu saja, pemrograman generik adalah masalah yang sama sekali berbeda, seperti yang disaksikan oleh Trilinos, kesepakatan.II (perpustakaan saya sendiri), DUNE, dan banyak perpustakaan lainnya - mengekspresikan konsep yang sama beroperasi pada tipe data yang berbeda adalah semacam no-brainer, dan sebagian besar masyarakat telah menerimanya selama masih dalam batas yang menghindari masalah metaprogramming. Saya pikir pemrograman generik memenuhi syarat sebagai keberhasilan yang jelas.
Tentu saja, tidak satu pun dari topik ini yang langsung terhubung ke OOP. OOP, sekali lagi, bisa saya katakan, diterima secara universal oleh komunitas komputasi ilmiah. Bahkan kurang dari pemrograman generik, ini bukan topik perdebatan: setiap perpustakaan yang berhasil ditulis dalam 15 tahun terakhir (apakah ditulis dalam C ++, C atau Fortran) menggunakan teknik OOP.
sumber
Izinkan saya memberi contoh berdasarkan pengalaman. Sebagian besar perpustakaan yang saya gunakan dari hari ke hari menggunakan OOP dalam beberapa cara. OOP mampu menyembunyikan kompleksitas yang diperlukan untuk banyak domain, ini bukan mekanisme yang sangat membantu kinerja. Apa yang bisa terjadi adalah bahwa perpustakaan dapat menggunakan optimasi tertentu berdasarkan hirarki objek, tetapi sebagian besar adalah tentang menyembunyikan kompleksitas dari pengguna. Lihat Pola Desain, mereka adalah mekanisme yang sering digunakan untuk mencapai kompleksitas bersembunyi ini.
Ambil PETSc sebagai contoh. PETSc menggunakan model inspektur / pelaksana OOP di mana setiap algoritmanya melihat rutinitas yang tersedia di objek tertentu dan memilih yang akan dieksekusi untuk menyelesaikan rutin. Hal ini memungkinkan pengguna untuk memisahkan masalah, misalnya tindakan matriks dapat mencakup segala jenis rutin yang diblokir atau dioptimalkan dan secara efektif digunakan oleh banyak pemecah iteratif. Dengan memberikan pengguna kemampuan untuk menentukan tipe data dan evaluasi mereka sendiri, mereka mendapatkan beberapa rutinitas penting dan juga memiliki seluruh fungsi perpustakaan masih tersedia.
Contoh lain yang akan saya berikan adalah FEniCS dan deal.II. Kedua perpustakaan ini menggunakan OOP untuk menggeneralisasi sejumlah besar Metode Elemen Hingga. Dalam segala hal mulai dari jenis elemen, urutan elemen, representasi quadrature, dan sebagainya dapat dipertukarkan. Walaupun kedua pustaka ini "lebih lambat" daripada beberapa kode FEM terstruktur dengan tujuan khusus, mereka mampu menyelesaikan berbagai masalah dengan banyak kompleksitas FEM yang tidak diketahui pengguna.
Contoh terakhir saya adalah Elemental. Elemental adalah perpustakaan aljabar linear padat baru yang telah mengambil kesulitan mengelola komunikator MPI dan lokasi data ke konstruksi bahasa yang sangat sederhana. Hasilnya adalah bahwa jika Anda memiliki kode serial FLAME, dengan mengubah tipe data Anda juga dapat memiliki kode paralel melalui Elemental. Yang lebih menarik Anda bisa bermain dengan distribusi data dengan mengatur distribusi yang sama dengan yang lain.
OOP harus dianggap sebagai cara untuk mengelola kompleksitas, bukan paradigma untuk bersaing dengan perakitan linting tangan. Juga melakukannya dengan buruk akan menghasilkan banyak overhead sehingga seseorang harus menjaga waktu dan memperbarui mekanisme yang mereka gunakan.
sumber
Apa fitur bahasa
OOP
lakukan untuk komputasi ilmiah adalah membuat pernyataan kode yang lebih kompak yang membantu dalam memahami dan menggunakan kode lebih baik. Sebagai contoh,FFT
rutinitas perlu membawa sejumlah besar argumen untuk setiap panggilan fungsi membuat kode rumit.Dengan menggunakan
module
atauclass
pernyataan hanya apa yang dibutuhkan pada saat panggilan dapat dilewati, karena sisa argumen berkaitan dengan pengaturan masalah (yaitu ukuran array, dan koefisien).Dalam pengalaman saya, saya memiliki
SUBROUTINE
panggilan dengan 55 argumen (masuk & keluar) dan saya mengurangi itu menjadi 5 membuat kode lebih baik.Itu nilai.
sumber
Saya seorang pendukung kuat pemrograman generik dan meta-pemrograman untuk komputasi ilmiah. Saya sebenarnya mengembangkan perpustakaan perangkat lunak C ++ gratis untuk metode Galerkin berdasarkan teknik yang disebut Feel ++ (http://www.feelpp.org) yang terus mendapatkan momentum. Benar bahwa masih ada kesulitan seperti waktu kompilasi yang lambat dan kurva belajar bisa curam jika seseorang ingin memahami apa yang terjadi di belakang layar. Namun ini sangat menarik dan mengejutkan. Jika dilakukan di tingkat pustaka dan menyembunyikan kompleksitas di balik bahasa khusus domain, Anda mendapatkan alat yang sangat kuat. Kami memiliki berbagai metode yang dapat kami gunakan dan bandingkan. Untuk tujuan pengajaran komputasi ilmiah ini luar biasa, untuk penelitian dan metode numerik baru juga, untuk aplikasi skala besar, baik kita mengerjakannya tapi sejauh ini bagus, kita sudah bisa melakukan beberapa hal yang bagus. Kami memiliki insinyur, fisikawan dan ahli matematika yang menggunakannya: kebanyakan dari mereka hanya menggunakan bahasa untuk formulasi variasi dan mereka senang dengan itu. Melihat beberapa formulasi yang dimanipulasi rekan fisikawan kita, saya tidak ingin melihat mereka dilakukan "dengan tangan" tanpa bahasa tingkat tinggi untuk menggambarkan formulasi variasional. Saya pribadi menganggap bahwa "teknik" atau "paradigma" ini sekarang diperlukan untuk mengatasi kompleksitas dalam kode komputasi ilmiah dengan harus mengalikan ukuran kode dengan faktor yang sangat besar. Mungkin ada kebutuhan untuk meningkatkan dukungan meta-pemrograman dalam C ++ tetapi sudah dalam kondisi yang baik terutama karena C ++ 11.
sumber
Anda mungkin menemukan makalah http://arxiv.org/abs/1104.1729 relevan dengan pertanyaan Anda. Ini membahas templat ekspresi (aplikasi tertentu dari meta-pemrograman templat yang digunakan dalam kode ilmiah) dari perspektif kinerja.
sumber
Template sangat bagus untuk menghapus pemeriksaan jenis / domain saat run-time. Ini dapat diurus pada saat kompilasi. Secara teori ini dapat meningkatkan kinerja dibandingkan dengan jenis implementasi yang sama di C atau Fortran di mana pengecekan tipe hanya dapat dilakukan pada saat run-time - pengecekan diterapkan dalam kode sumber. Namun, Anda dapat mencapai hasil yang sama dalam C menggunakan opsi precompiler tetapi ini harus dilakukan dengan tangan tidak seperti template.
Namun, templat dapat menghasilkan overhead yang signifikan juga. Mereka sering dapat membuat kode mengasapi yang dapat berdampak pada penggunaan cache instruksi. Lebih jauh lagi, pendekatan generik sering dapat membelenggu kompiler selama optimasi - tidak selalu mudah untuk analisis kode ketika menggunakan pendekatan generik. Selalu ada masalah dengan otomatisasi - termasuk optimisasi kompiler - sangat sering kode output tidak ramah cache.
Manfaat dari pengecekan jenis / domain, meskipun tentu saja lebih aman, adalah satu-satunya manfaat nyata yang dapat saya lihat dalam hal kinerja dan ini biasanya tidak terlihat. Tapi seperti yang saya katakan efek keseluruhan bisa negatif tergantung apa yang Anda lakukan. Itu sebabnya seringkali lebih baik untuk mengoptimalkan kode Anda secara manual di mana Anda mengalami hambatan yang signifikan.
sumber