Bahasa pemrograman di mana setiap panggilan fungsi / blok dilakukan dalam utas terpisah? [Tutup]

26

Saat ini saya sedang membuat bahasa pemrograman untuk bersenang-senang di mana idenya adalah bahwa setiap panggilan fungsi / blok baru (jika klausa, loop dll) akan bekerja di utas terpisah. Alih-alih membuat Thread baru, standarnya haruslah yang melakukan itu secara otomatis, dan jika Anda ingin menjalankannya di utas utama Anda harus menentukan itu.

Saya tidak tahu tentang multi-threaded, pemrograman paralel tapi saya tahu dasar-dasarnya (Futures, objek aman thread). Karena itu saya bertanya-tanya bagaimana bahasa seperti itu dapat terlihat sintaksis dan apakah mungkin untuk memulainya? Tujuannya bukan untuk membuatnya "berguna", itu lebih untuk bersenang-senang dan pengalaman belajar.

(Maaf jika ini adalah tempat yang salah untuk memposting. Jika demikian, saya akan dengan senang hati menghargai jika Anda mengarahkan saya ke tempat yang tepat di mana pertanyaan seperti milik saya diizinkan.)

Grimbox
sumber
17
Membuat utas sederhana. Trik dengan multi-threading adalah ketika mereka perlu berbicara satu sama lain atau bekerja dengan sumber daya yang sama. Dengan kata lain, bukan forking yang sulit, melainkan gabungannya. Masalah utama yang perlu Anda pecahkan adalah bagaimana Anda mengendalikannya.
JimmyJames
20
IMO, Anda tidak dapat melakukan itu tanpa secara serius memperluas definisi kata "fungsi" atau kata "utas". Anda mungkin ingin membaca tentang aktor jika Anda belum terbiasa dengan mereka: en.wikipedia.org/wiki/Actor_model
Solomon Slow
9
Dapatkan cukup berbutir halus, dan Anda akan menemukan bahwa CPU sudah memparalelkan instruksi secara otomatis, tanpa membebani pengembang perangkat lunak. Lihat Eksekusi yang Tidak Beraturan dan Prosesor Superscalar .
8bittree
8
Itu sebenarnya terdengar agak mengerikan. Saya akan menjelaskan alasannya, tetapi Karl Bielefeldt sudah melakukannya.
Mason Wheeler
1
Paradigma macam apa yang ingin Anda dukung dalam bahasa Anda? Haruskah itu penting atau fungsional? Apakah Anda mengatakan bahwa semua pernyataan akan dieksekusi pada saat yang sama - blok saat itu / bersama-sama dengan apa yang datang setelah mereka?
Bergi

Jawaban:

39

setiap panggilan fungsi / blok baru (jika klausa, loop, dll) akan bekerja di utas terpisah.

Baca lebih banyak tentang kelanjutan dan gaya kelanjutan-kelanjutan (dan kaitannya dengan utas atau coroutine) Saya sarankan untuk membaca SICP & Lisp In Small Pieces . Juga, Memprogram Bahasa Pragmatik memberikan ikhtisar yang berguna dari beberapa bahasa, dan akan membantu Anda untuk merancang bahasa Anda sendiri.

Karena itu saya bertanya-tanya bagaimana bahasa seperti itu bisa terlihat sintaks

Sintaks tidak terlalu penting untuk mengeksplorasi ide . Semantik lebih penting. Saya menyarankan untuk mengadopsi beberapa S-expr seperti sintaks (sehingga Anda bisa membuat prototipe menggunakan Skema dan panggilannya / cc ) pada awalnya.

Setelah ide Anda lebih jelas (setelah beberapa percobaan), Anda dapat mendiskusikannya di lambda-the-ultimate , Anda dapat mendefinisikan sintaksis yang lebih seksi (yang sebenarnya penting jika Anda ingin orang mengadopsi bahasa Anda, dan yang juga penting adalah kualitasnya. implementasi, implementasi sampel perangkat lunak bebas, dokumentasi, perpustakaan standar, antarmuka fungsi asing, dll)

Basile Starynkevitch
sumber
25
+1 untuk penyebutan mengapa sintaksis tidak relevan. +1 lain jika saya bisa menjelaskan mengapa sintaks sangat penting.
Jörg W Mittag
Saran yang bagus, tetapi untuk membahas hal-hal tentang LtU Anda ingin memiliki akun dan tidak sepele untuk mendapatkannya dari pengalaman saya.
Mael
1
Anda harus menggunakan kumpulan utas untuk mengurangi overhead. en.wikipedia.org/wiki/Thread_pool
shawnhcorey
37

Anda mungkin tertarik membaca tentang penelitian Haskell terhadap data paralel . Jika Anda mencari-cari di youtube, Simon Peyton Jones telah memberikan beberapa pembicaraan menarik terkait dengan subjek juga.

Jika saya ingat benar dari pembicaraannya, dalam pemrograman fungsional murni, hampir sepele untuk menemukan peluang untuk membuat utas. Masalah utamanya dalam penelitiannya adalah memiliki terlalu banyak yang berumur pendek, sehingga overhead menciptakan benang dan mengkomunikasikan hasil mereka pada dasarnya lebih besar daripada manfaat paralelisme. Sebagai contoh, mudah untuk mengajarkan kompiler untuk memutar 100 utas untuk dikomputasi sum $ fmap (+1) <100 length vector>, tetapi apakah overhead membuatnya berharga?

Triknya adalah mengkonsolidasikan utas ke dalam ukuran yang menguntungkan, tanpa membebani pemrogram untuk menunjukkannya secara manual. Ini masalah sulit yang perlu dipecahkan agar dapat secara efektif menggunakan PC masa depan dengan ribuan inti.

Karl Bielefeldt
sumber
8
Saya sudah senang bekerja dengan PC kuno dengan hanya ratusan inti ...
Hagen von Eitzen
8
Saya akan memberikan catatan bahwa untuk desain paralel data yang banyak, kami telah melakukan banyak paralelisasi dengan sangat efektif: GPU pada dasarnya adalah 200-1000 mesin inti (mereka bahkan memiliki hierarki memori sendiri).
Delioth
4
@HagenvonEitzen: Azul Vega JCA (Java Compute Appliance) memiliki 16 CPU dengan 54 core masing-masing dengan total 864 core, dan itu bukan mesin level riset atau prototipe, tetapi produk nyata. Itu juga tidak memenuhi seluruh bangunan atau bahkan seluruh ruangan, itu adalah alat ukuran meja. Dan itu tersedia 9 tahun yang lalu. GPU sudah disebutkan, ini, bagaimanapun, adalah mesin dengan 864 core CPU tujuan umum .
Jörg W Mittag
3
Tentu saja, ada alasan mengapa kita tidak memiliki orang-orang besar GPU data paralel hari ini, tetapi tidak lagi mereka besar CPU multi-core adalah untuk desktop. Yang pertama layak secara komersial, yang terakhir tidak, dan itu karena Anda tidak bisa memprogram mereka secara efisien.
MSalters
@Malters mungkin kita hanya perlu jumlah monyet yang tak terbatas? Atau, program Quantum yang hanya menjalankan setiap operasi yang mungkin pada setiap langkah?
15

Inilah yang dilakukan Erlang. Ini menangani bergabung kembali dengan utas sebagian besar dengan menggunakan antrian. Ini adalah konsep yang brilian tetapi agak sulit untuk membungkus kepala Anda awalnya jika latar belakang Anda adalah bahasa jenis yang lebih prosedural. Saya sangat merekomendasikan melihatnya.

GenericJam
sumber
4

Pertama saya akan merekomendasikan Anda melihat PROMELA , bahasa yang digunakan untuk menggambarkan algoritma bersamaan sehingga pemeriksa model dapat memaksa semua eksekusi yang mungkin untuk memverifikasi itu tidak mampu melakukan perilaku yang salah. (Pemrograman bersamaan terkenal sulit untuk dilakukan dengan benar, itulah sebabnya teknik verifikasi seperti itu penting.) Ia tidak menjalankan semua konstruksi dalam utas yang terpisah, tetapi memang memiliki sintaks dan semantik yang agak aneh karena fokusnya adalah non determinisme dari program bersamaan.

Lebih abstrak, kalkulus π adalah pendekatan yang indah untuk memodelkan komputasi paralel. Sulit untuk membuat kepala Anda di sekitar kecuali Anda mendapatkan buku itu Communicating and Mobile Systems: The Pi Calculus , oleh Robin Milner. Ini membantu saya berpikir tentang komputasi paralel dalam arti yang lebih luas bahwa "banyak utas mengakses memori bersama". Sangat menarik bagaimana pernyataan bersyarat, "gotos" dan sebagainya dapat dibangun dari primitif paralel yang lebih sederhana dan alami.

Berkenaan dengan sintaks ... cara terbaik untuk menyelesaikannya adalah dengan menulis beberapa program sampel. Tulis program untuk mengurutkan array, atau secara bersamaan melakukan ping ke beberapa server dan melaporkan mana yang paling cepat direspon, atau mencoba memecahkan labirin secara paralel, atau yang lainnya. Saat Anda melakukan ini, hal-hal yang hilang dari sintaks Anda akan menjadi jelas, dan Anda dapat menambahkannya. Setelah Anda menambahkan beberapa hal, tanyakan pada diri Anda apakah mereka memiliki sesuatu yang sama, dan jika demikian mungkin Anda dapat menemukan pendekatan yang lebih sederhana yang dapat melayani berbagai tujuan.

Artelius
sumber
4

Proyek serupa telah dicoba di masa lalu. Saya sarankan membaca klasik untuk menjarah ide. (Semua tautan menuju Wikipedia)

  • Unity Bahasa ini dulu / digunakan untuk mengajar pemrograman paralel. Saya tidak berpikir itu benar-benar dilaksanakan. Sintaksis agak samar, tetapi pada dasarnya Anda memiliki kumpulan pernyataan yang dieksekusi dalam urutan yang tidak diketahui dan berulang kali sampai tidak ada lagi yang bisa dilakukan. Ini paling dekat dengan apa yang Anda minta.

  • Occam Bahasa ini dirancang untuk benar-benar menggunakan tetapi tidak pernah benar-benar menarik perhatian. Di sini ada kata kunci PAR yang berarti bahwa daftar pernyataan harus dieksekusi secara paralel.

  • Erlang Bahasa lain di dunia nyata. Yang ini digunakan oleh perusahaan telekomunikasi Ericsson dan memiliki cukup banyak pengikut. Mereka telah bekerja keras untuk membuat paralelisme menjadi praktis dan bermanfaat.

  • Google GO Ini adalah favorit saya dari banyak orang. Secara konseptual sama dengan Erlang, tetapi dengan sintaksis yang lebih baik dan bobot Google di belakangnya. Apa yang salah bisa terjadi?

Saya ingin menutup dengan peringatan: Paralelisme sangat sulit untuk diperbaiki. Sebagian besar bug dalam program modern adalah hasil dari kesalahan . Anda yakin ingin ke sana?

Stig Hemmer
sumber
Tidak ada pelanggaran yang ditujukan untuk bahasa apa pun yang tidak ada dalam daftar saya. Hanya saja pengetahuan saya terbatas.
Stig Hemmer
3

Itu mungkin tetapi itu tidak akan berguna untuk 99+% dari semua aplikasi yang masuk akal. Logika adalah urutan-terikat urutan, ini adalah aliran. Langkah demi langkah Anda mencapai solusi untuk masalah dan urutan langkah-langkah itu penting, terutama karena output dari satu langkah akan menjadi input untuk langkah berikutnya.

Dalam beberapa kasus Anda memang memiliki banyak tugas yang dapat dilakukan secara independen satu sama lain, biasanya murah untuk mengaturnya secara berurutan sebelum membiarkannya berjalan secara paralel.

Jadi, saya pikir waktu Anda akan lebih baik dihabiskan untuk belajar bagaimana menggunakan fitur multi-threading dalam bahasa pemrograman favorit Anda.

Martin Maat
sumber
5
Ini adalah jawaban yang bagus untuk pertanyaan yang berbeda; OP tidak bertanya tentang kebijaksanaan skema semacam itu tetapi hanya apakah itu dapat dilakukan dan seperti apa "sintaksis" itu.
DepressedDaniel
9
Mereka yang tidak memintanya paling membutuhkan kebijaksanaan saya. Jika seseorang bertanya apakah mungkin untuk turun bukit di kereta belanja, jawaban terbaik tidak akan menjadi "Anda bertaruh! Pastikan untuk meminyaki roda mereka!". Akan lebih seperti "Yah, ya, tapi ...".
Martin Maat
Mengingatkan saya pada instruksi bahasa assembly EIAO lama - Jalankan Dalam Urutan Apa Pun . (Dan di mana itu Any Key?)
@MartinMaat tidak ada yang akan bunuh diri dengan menulis bahasa pemrograman untuk bersenang
user253751
2

Clojure mungkin layak dicoba untuk beberapa ide.

http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

Berikut adalah beberapa pemikiran: Jika kita memanggil unit perhitungan yang dapat dilakukan secara mandiri tugas: 1. Tugas independen sehingga dapat dijalankan secara bersamaan 2. Tugas yang berbeda membutuhkan sumber daya yang berbeda dan mengambil waktu yang berbeda untuk menjalankan 3. Oleh karena itu tugas harus dijadwalkan untuk throughput maksimum 4. Satu-satunya program dalam posisi untuk bertindak sebagai penjadwal adalah sistem operasi

Hal-hal seperti pengiriman pusat apel besar adalah upaya untuk menyediakan penjadwal tersebut.

Di atas berarti bahwa tanggung jawab melaksanakan tugas tidak harus tanggung jawab dari bahasa pemrograman.

Pikiran kedua adalah mengurangi beban pemrograman sistem paralel sebanyak mungkin. Satu-satunya cara untuk melakukan ini adalah menghapus spesifikasi apa pun tentang bagaimana sesuatu harus dilakukan dari program. Suatu program seharusnya hanya menentukan apa yang harus dilakukan dan sisanya harus terjadi secara otomatis.

Di atas mungkin berarti bahwa bahasa dinamis dan kompilasi tepat waktu adalah cara untuk pergi.

foobar
sumber
2

Apa yang Anda cari disebut parallellism implisit, dan ada bahasa yang telah mengeksplorasi konsep ini, seperti Sun / Oracle's Fortress . Antara lain, itu (berpotensi) menjalankan loop paralel.

Sayangnya, itu sudah dihentikan dan ada banyak tautan mati di luar sana, tetapi Anda masih dapat menemukan beberapa PDF mengambang di sana, jika Anda google cukup keras:

https://www.eecis.udel.edu/~cavazos/cisc879-spring2008/papers/fortress.pdf (spesifikasi bahasa)

http://stephane.ducasse.free.fr/Teaching/CoursAnnecy/0506-Master/ForPresentations/Fortress-PLDITutorialSlides9Jun2006.pdf

http://www.oracle.com/technetwork/systems/ts-5206-159453.pdf

http://dl.acm.org/citation.cfm?id=1122972 (paywalled)

Yang perlu diperhatikan adalah bahwa Anda biasanya tidak ingin memulai utas aktual untuk setiap pernyataan / ungkapan, karena membuat dan memulai utas cenderung mahal - sebagai gantinya, Anda akan memiliki kumpulan utas tempat Anda memposting bit pekerjaan yang perlu dilakukan . Tapi itu detail implementasi.

Gustaf
sumber
1
+1 untuk mantioning Fortress ... Saya sangat menyukai gagasan bahasanya. Saya sangat sedih ketika mereka mengumumkan bahwa pengembangan dihentikan ...
Roland Tepp
2

Meskipun bukan bahasa pemrograman seperti itu, Anda harus melihat VHDL . Ini digunakan untuk menggambarkan sirkuit digital, yang secara alami melakukan semuanya secara paralel kecuali Anda secara khusus menyuruhnya melakukannya secara serial. Ini mungkin memberi Anda beberapa ide bagaimana merancang bahasa Anda dan jenis logika apa yang cocok untuk itu.

OnePie
sumber
0

Ini dapat disimulasikan dengan cukup mudah di C ++. Pastikan saja bahwa "setiap" * panggilan fungsi diimplementasikan oleh a std::future. Menangani nilai balik hanya dilakukan dengan memanggil .get()masa depan.

Karenanya, Anda dapat membuat prototipe bahasa Anda dengan mengkompilasi ke C ++. Ini juga memberi tahu kita seperti apa sintaksisnya: perbedaan utama adalah bahwa Anda memisahkan titik panggilan (di mana argumen input disediakan) dari titik kembali (di mana fungsi output digunakan).

(*) Saya katakan "setiap fungsi" tetapi terserah Anda apa yang dianggap sebagai fungsi. Apakah memsetintrinsik atau fungsi? Apakah penugasan bilangan bulat, atau penugasan tipe yang ditentukan pengguna adalah panggilan fungsi?

MSalters
sumber
Dan, jika Anda menunda menjawab pertanyaan cukup lama, biasanya kebutuhan akan jawaban hilang. Saya pikir ini disebut "Malas Yang Ada".