Perbedaan antara pemrograman Paralel dan Bersamaan?

44

Ketika melihat pemrograman konkuren, dua istilah yang umum digunakan yaitu konkuren dan paralel.

Dan beberapa bahasa pemrograman secara khusus mengklaim dukungan untuk pemrograman paralel, seperti Java .

Apakah ini berarti pemrograman paralel dan konkuren sebenarnya berbeda?

nish1013
sumber
10
Ya, pemrograman paralel dan paralel berbeda. misalnya, Anda dapat memiliki dua utas (atau proses) yang dijalankan bersamaan pada inti yang sama melalui pengalihan konteks. Ketika dua utas (atau proses) dieksekusi pada dua inti yang berbeda (atau prosesor), Anda memiliki paralelisme. Jadi, dalam paralelisme kasus sebelumnya (konkurensi) hanya "virtual", sedangkan di yang kedua Anda memiliki paralelisme sejati. Oleh karena itu, setiap program paralel bersamaan, tetapi kebalikannya tidak selalu benar.
Massimo Cafaro
1
Hati-hati di sini. Anda dapat mencapai hasil yang sama baik melalui dukungan bahasa (yaitu, memperluas bahasa dengan konstruksi baru) atau menggunakan pendekatan tingkat rendah (misalnya, dengan menggunakan perpustakaan, seperti dalam kasus MPI dan OpenMP). Bagaimanapun, dengan prosesor multicore saat ini dan sistem operasi dengan dukungan SMP, program yang akan bersamaan jika dijalankan pada prosesor single-core lama, dapat dieksekusi secara paralel jika OS menjadwalkan utas-utas pelaksanaan program pada inti yang berbeda. Jadi, perbedaannya sedikit "kabur" saat ini.
Massimo Cafaro
3
Apa yang Anda gunakan untuk kecepatan latensi cahaya konstan. Dalam konkurensi, Anda menganggap kecepatan latensi cahaya adalah satu siklus clock. Secara paralel Anda menganggap satu server berada di sebelah, di dalam distribusi Anda menganggap satu server ada di Mars.
1
Robert Harper membahas masalah ini dalam dua posting blog, "Paralelisme bukan konkurensi" dan "Paralelisme dan Konkurensi, Ditinjau Kembali" , yang mungkin ingin Anda periksa.
Basil

Jawaban:

26

Bedakan paralelisme (menggunakan unit komputasi ekstra untuk melakukan lebih banyak pekerjaan per unit waktu) dari concurrency (mengelola akses ke sumber daya bersama). Ajari paralelisme terlebih dahulu karena lebih mudah dan membantu membangun pola pikir yang tidak berurutan.

Dari "A Sophomoric ∗ Pengantar Paralelisme dan Memori Bersama-Memori Bersama" oleh Dan Grossman (versi 16 November 2013)

Raphael
sumber
21

Selain jawaban Nish, izinkan saya merekomendasikan buku Simon Marlow tentang Pemrograman Paralel dan Bersamaan di Haskell atau tutorialnya yang lebih pendek . Mereka menjawab pertanyaan pertama Anda dari perspektif Haskell, sehingga mereka bisa lebih cocok untuk pembaca yang cenderung secara teoritis (Haskell adalah murni bahasa pemrograman yang malas dan fungsional, yang jauh lebih dekat dengan Matematika daripada bahasa lain).

Mengutip dari sana:

Dalam banyak bidang, kata-kata paralel dan konkuren adalah sinonim; tidak demikian dalam pemrograman, di mana mereka digunakan untuk menggambarkan konsep yang berbeda secara fundamental.

Program paralel adalah program yang menggunakan banyak perangkat keras komputasi (misalnya beberapa inti prosesor) untuk melakukan komputasi lebih cepat. Bagian-bagian yang berbeda dari komputasi didelegasikan ke prosesor yang berbeda yang mengeksekusi pada saat yang sama (secara paralel), sehingga hasilnya dapat disampaikan lebih awal daripada jika perhitungan dilakukan secara berurutan.

Sebaliknya, konkurensi adalah teknik penataan program di mana ada beberapa untaian kontrol. Secara alami utas kontrol menjalankan "pada saat yang sama"; yaitu, pengguna melihat efeknya disisipkan. Apakah mereka benar-benar mengeksekusi pada saat yang sama atau tidak adalah detail implementasi; program konkuren dapat dijalankan pada satu prosesor melalui eksekusi berlevel, atau pada beberapa prosesor fisik.

Saya merekomendasikan membaca sisanya dalam tutorial (hal.4), tetapi izinkan saya mengutip beberapa bagian lain dari bagian ini, karena ini menghubungkan kedua paradigma pemrograman dengan karakteristik kuantitatif dan kualitatif dari program, seperti efisiensi, modularitas, dan determinisme.

Sementara pemrograman paralel hanya berkaitan dengan efisiensi, pemrograman bersamaan berkaitan dengan penataan program yang perlu berinteraksi dengan beberapa agen eksternal independen (misalnya pengguna, server database, dan beberapa klien eksternal). Concurrency memungkinkan program tersebut bersifat modular; utas yang berinteraksi dengan pengguna berbeda dari utas yang berbicara ke basis data. Dengan tidak adanya konkurensi, program semacam itu harus ditulis dengan loop peristiwa dan callback --- memang, loop peristiwa dan callback sering digunakan bahkan ketika konkurensi tersedia, karena dalam banyak bahasa konkurensi terlalu mahal, atau terlalu sulit, untuk menggunakan.

Gagasan "utas kontrol" tidak masuk akal dalam program yang murni fungsional, karena tidak ada efek untuk diamati, dan urutan evaluasi tidak relevan. Jadi concurrency adalah teknik penataan kode yang efektif; di Haskell, itu berarti kode di monad IO.

Perbedaan terkait adalah antara model pemrograman deterministik dan nondeterministik. Model pemrograman deterministik adalah model di mana setiap program hanya dapat memberikan satu hasil, sedangkan model pemrograman nondeterministik mengakui program yang mungkin memiliki hasil yang berbeda, tergantung pada beberapa aspek pelaksanaannya. Model-model pemrograman bersamaan selalu nondeterministik, karena mereka harus berinteraksi dengan agen eksternal yang menyebabkan peristiwa pada waktu yang tidak terduga. Namun, Nondeterminisme memiliki beberapa kelemahan: program menjadi jauh lebih sulit untuk diuji dan dipikirkan.

Untuk pemrograman paralel, kami ingin menggunakan model pemrograman deterministik jika memungkinkan. Karena tujuannya hanya untuk mendapatkan jawaban lebih cepat, kami lebih suka tidak membuat program kami lebih sulit untuk di-debug dalam proses. Pemrograman paralel deterministik adalah yang terbaik dari kedua dunia: pengujian, debugging dan penalaran dapat dilakukan pada program berurutan, tetapi program berjalan lebih cepat ketika prosesor ditambahkan. Memang, sebagian besar prosesor komputer sendiri menerapkan paralelisme deterministik dalam bentuk pipelining dan beberapa unit eksekusi.

Meskipun dimungkinkan untuk melakukan pemrograman paralel menggunakan konkurensi, itu sering merupakan pilihan yang buruk, karena konkurensi konkurensi konkurensi. Dalam Haskell, model pemrograman paralel bersifat deterministik. Namun, penting untuk dicatat bahwa model pemrograman deterministik tidak cukup untuk mengekspresikan semua jenis algoritma paralel; ada algoritma yang bergantung pada nondeterminisme internal, terutama masalah yang melibatkan pencarian ruang solusi. Di Haskell, kelas algoritma ini hanya dapat diekspresikan dengan menggunakan konkurensi.

Nickie
sumber
20

Conurrency dan paralelisme berbeda dalam masalah yang mereka pecahkan dan sebabkan, tetapi mereka tidak independen.

Konkurensi

Menjalankan dua tugas secara bersamaan berarti bahwa langkah-langkah individual dari kedua tugas dijalankan secara interleaved. Jika Anda mengabaikan paralelisme, Anda dapat mengasumsikan bahwa hanya satu pernyataan yang dieksekusi pada suatu titik waktu, tetapi Anda (a priori) tidak memiliki jaminan tugas mana yang dapat dijalankan untuk langkah selanjutnya.

Ini berguna dalam beberapa hal:

  • Pemrograman tugas independen yang lebih jelas dalam satu program.
  • Memungkinkan berurusan dengan IO saat komputasi (misalnya dalam GUI).
  • Mengizinkan pelaksanaan lebih dari satu program sekaligus (konkurensi pada tingkat OS).

Beberapa tantangan utama adalah:

  • Pertahankan konsistensi data.
  • Hindari deadlock dan livelocks .
  • Tentukan semantik yang tepat dari proses bersamaan.
  • Tentukan properti statis yang memastikan kebenaran.

Paralelisme

Menjalankan dua tugas secara paralel berarti bahwa pernyataan dieksekusi pada saat yang sama . Ini terutama berguna untuk:

  • Meningkatkan throughput sistem dengan menjalankan program secara paralel (mis. Pada sistem multi-inti).
  • Tingkatkan runtime dari masing-masing program dengan memanfaatkan banyak CPU sekaligus.
  • Memanfaatkan IO pada banyak mesin (mis. Database terdistribusi).

Tantangan utama meliputi:

  • Masalah partisi yang memungkinkan dan mengembangkan algoritma yang dapat menggunakan paralelisme.
  • Meminimalkan ketergantungan dan komunikasi antara unit komputasi.
  • Semua masalah yang dibawa oleh konkurensi: setidaknya dari sudut pandang memori, program paralel terlihat seperti yang bersamaan karena serialisasi akses memori.
  • Menangani dukungan perangkat keras yang kurang optimal.

Lihat juga pertanyaan ini untuk membedakan komputasi paralel dan terdistribusi.

Raphael
sumber
5

Jawaban yang sedikit ideal, mungkin ...

  • Concurrency adalah properti dari bagaimana suatu program ditulis . Jika suatu program ditulis menggunakan konstruksi seperti fork / join, kunci, transaksi, operasi perbandingan-dan-pertukaran atom, dan sebagainya, maka itu bersamaan.

  • Paralelisme adalah properti dari bagaimana suatu program dijalankan . Jika suatu program dieksekusi pada lebih dari satu unit komputasi secara bersamaan, maka ia dijalankan secara paralel.

John Wickerson
sumber
1

Ada banyak jawaban untuk ini, tetapi bisa membingungkan. Saya suka berpikir seperti ini, dan mungkin itu membantu ?:

Pemrograman bersamaan adalah kode yang tidak peduli dengan urutan eksekusi. Java adalah bahasa yang buruk untuk pemrograman bersamaan, tetapi ada perpustakaan dan kerangka kerja untuk membantu. JavaScript adalah bahasa yang sangat baik untuk pemrograman bersamaan, dan seringkali sulit ketika Anda ingin menulis sesuatu yang tidak bersamaan (misalnya, jika Anda ingin memaksakan urutan eksekusi). Pemrograman bersamaan sangat bagus untuk pemrograman yang digerakkan oleh acara (di mana urutan eksekusi ditentukan oleh pendengar acara, seperti kode yang berjalan di browser Anda yang bekerja ketika Anda mengklik tombol atau mengetik ke dalam kotak).

Contohnya termasuk membuat seratus permintaan HTTP. Di NodeJS, solusi paling sederhana adalah membuka semua 100 permintaan sekaligus dengan metode panggilan balik, dan ketika respons kembali, metode dijalankan setiap kali. Itu pemrograman bersamaan. Di Ruby, solusi paling sederhana (paling umum) adalah membuka permintaan dan menangani respons, membuka permintaan berikutnya dan menangani respons, dll. Untuk banyak permintaan, NodeJS lebih mudah dilakukan secara tepat waktu, meskipun Anda harus hati-hati untuk menghindari memalu server atau memaksimalkan koneksi keluar Anda (mudah dilakukan karena kesalahan). Anda dapat menulis Ruby secara bersamaan, tetapi bukan bagaimana sebagian besar kode Ruby ditulis, dan sedikit menyakitkan untuk melakukannya.

Pemrograman paraleladalah kode yang dapat dijalankan secara bersamaan di banyak utas atau proses. Ini memungkinkan Anda untuk mengoptimalkan kinerja dengan menjalankan kode di beberapa CPU (seringkali termasuk beberapa mesin, seperti yang Anda lakukan dengan sesuatu seperti Akka). Karena NodeJS bukan multi-threaded dan tidak ada eksekusi paralel, Anda tidak perlu khawatir menulis kode threadsafe (dan sebagian besar kode JavaScript yang saya lihat bukan threadsafe). Di Jawa, meskipun bahasa tidak menjadikan pemrograman bersamaan sebagai pola normal, pemrograman paralel sangat terintegrasi, dan Anda sering harus khawatir tentang keamanan utas. Jika Anda menulis situs web di Java, biasanya ini akan dijalankan dalam wadah yang menjalankan setiap permintaan dalam utas terpisah di memori yang sama,


Beberapa hal di atas tergantung pada ruang lingkup dan batasan yang Anda bicarakan. Saya bekerja di Situs Web. Kebanyakan kode Java yang saya lihat bukan pemrograman bersamaan. Tentu, jika Anda memperkecil cukup, urutan yang diminta pelanggan tidak penting, tetapi jika Anda memperbesar lebih jauh dari itu, urutan hal-hal yang dieksekusi ditentukan oleh kode. Tetapi kode ini ditulis sehingga permintaan dapat dieksekusi secara paralel dengan banyak objek bersama yang harus diamankan.

Sementara itu, sebagian besar kode JavaScript yang saya lihat bersamaan: ditulis sedemikian rupa sehingga urutan pelaksanaannya tidak penting di banyak tingkatan. Tetapi tidak ditulis untuk mendukung eksekusi paralel dalam memori bersama. Tentu, Anda dapat menjalankan kode yang sama secara paralel di beberapa proses, tetapi objek tidak dibagi, jadi itu bukan pemrograman paralel dalam arti yang berarti.

Untuk bacaan tambahan, saya sangat suka ilustrasi di jawaban atas pertanyaan ini di sini: https://www.quora.com/What-are-the-differences-between-parallel-concurrent-and-asynchronous-programming

Jun-Dai Bates-Kobashigawa
sumber