Mereka adalah dua frasa yang menggambarkan hal yang sama dari (sangat sedikit) sudut pandang yang berbeda. Pemrograman paralel menggambarkan situasi dari sudut pandang perangkat keras - setidaknya ada dua prosesor (mungkin dalam satu paket fisik) yang bekerja pada masalah secara paralel. Pemrograman bersamaan menggambarkan hal-hal lebih dari sudut pandang perangkat lunak - dua atau lebih tindakan dapat terjadi pada waktu yang sama (bersamaan).
Masalahnya di sini adalah bahwa orang-orang mencoba menggunakan dua frasa untuk menarik perbedaan yang jelas ketika tidak ada yang benar-benar ada. Kenyataannya adalah bahwa garis pemisah yang mereka coba gambar telah kabur dan tidak jelas selama beberapa dekade, dan telah tumbuh semakin tidak jelas seiring waktu.
Apa yang mereka coba diskusikan adalah fakta bahwa pada suatu waktu, kebanyakan komputer hanya memiliki satu CPU. Ketika Anda menjalankan banyak proses (atau utas) pada CPU tunggal itu, CPU hanya benar-benar menjalankan satu instruksi dari salah satu utas tersebut sekaligus. Munculnya konkurensi adalah ilusi - pergantian CPU antara menjalankan instruksi dari utas yang berbeda cukup cepat dengan persepsi manusia (yang mana kurang dari 100 ms atau lebih terlihat seketika) sepertinya melakukan banyak hal sekaligus.
Kontras yang jelas untuk ini adalah komputer dengan banyak CPU, atau CPU dengan banyak inti, sehingga mesin menjalankan instruksi dari banyak utas dan / atau proses pada waktu yang bersamaan; mengeksekusi kode yang satu tidak bisa / tidak memiliki efek pada mengeksekusi kode yang lain.
Sekarang masalahnya: perbedaan bersih seperti itu hampir tidak pernah ada. Desainer komputer sebenarnya cukup cerdas, sehingga mereka memperhatikan sejak lama bahwa (misalnya) ketika Anda perlu membaca beberapa data dari perangkat I / O seperti disk, butuh waktu lama (dalam hal siklus CPU) untuk selesai. Alih-alih membiarkan CPU menganggur saat itu terjadi, mereka menemukan berbagai cara untuk membiarkan satu proses / utas membuat permintaan I / O, dan membiarkan kode dari beberapa proses / utas lain dijalankan pada CPU sementara permintaan I / O selesai.
Jadi, jauh sebelum CPU multi-core menjadi norma, kami memiliki operasi dari banyak utas yang terjadi secara paralel.
Itu hanya puncak gunung es sekalipun. Beberapa dekade yang lalu, komputer juga mulai menyediakan level paralelisme lain. Sekali lagi, sebagai orang yang cukup cerdas, perancang komputer memperhatikan bahwa dalam banyak kasus, mereka memiliki instruksi yang tidak saling mempengaruhi, sehingga dimungkinkan untuk menjalankan lebih dari satu instruksi dari aliran yang sama pada saat yang bersamaan. Salah satu contoh awal yang menjadi cukup terkenal adalah Data Kontrol 6600. Ini (dengan margin yang cukup lebar) komputer tercepat di dunia ketika diperkenalkan pada tahun 1964 - dan banyak arsitektur dasar yang sama tetap digunakan sampai sekarang. Ini melacak sumber daya yang digunakan oleh setiap instruksi, dan memiliki satu set unit eksekusi yang mengeksekusi instruksi segera setelah sumber daya yang mereka andalkan menjadi tersedia, sangat mirip dengan desain prosesor Intel / AMD terbaru.
Tapi (seperti yang sering dikatakan iklan) tunggu - itu belum semuanya. Masih ada elemen desain lain untuk menambah kebingungan lebih lanjut. Sudah diberi beberapa nama yang berbeda (misalnya, "Hyperthreading", "SMT", "CMP"), tetapi mereka semua merujuk pada ide dasar yang sama: CPU yang dapat mengeksekusi banyak utas secara bersamaan, menggunakan kombinasi beberapa sumber daya yang independen untuk setiap utas, dan beberapa sumber daya yang dibagi di antara utas. Dalam kasus khusus ini dikombinasikan dengan paralelisme tingkat instruksi yang diuraikan di atas. Untuk melakukan itu, kami memiliki dua (atau lebih) set register arsitektur. Kemudian kami memiliki satu set unit eksekusi yang dapat menjalankan instruksi segera setelah sumber daya yang diperlukan tersedia.
Kemudian, tentu saja, kita sampai pada sistem modern dengan banyak inti. Di sini segalanya sudah jelas, bukan? Kami memiliki N (di suatu tempat antara 2 dan 256 atau lebih, pada saat ini) core yang terpisah, yang semuanya dapat menjalankan instruksi pada saat yang sama, jadi kami memiliki kasus paralelisme nyata yang jelas - mengeksekusi instruksi dalam satu proses / thread tidak t mempengaruhi pelaksanaan instruksi di tempat lain.
Yah, semacam itu. Bahkan di sini kita memiliki beberapa sumber daya independen (register, unit eksekusi, setidaknya satu tingkat cache) dan beberapa sumber daya bersama (biasanya setidaknya tingkat cache terendah, dan tentunya pengontrol memori dan bandwidth ke memori).
Untuk meringkas: skenario sederhana yang orang suka kontras antara sumber daya bersama dan sumber daya independen hampir tidak pernah terjadi dalam kehidupan nyata. Dengan semua sumber daya dibagikan, kita berakhir dengan sesuatu seperti MS-DOS, di mana kita hanya dapat menjalankan satu program pada satu waktu, dan kita harus berhenti menjalankan satu sebelum kita dapat menjalankan yang lain sama sekali. Dengan sumber daya yang sepenuhnya independen, kami memiliki N komputer yang menjalankan MS-DOS (bahkan tanpa jaringan untuk menghubungkan mereka) tanpa kemampuan untuk berbagi apa pun di antara mereka sama sekali (karena jika kami bahkan dapat berbagi file, well, itu adalah sumber daya bersama, sebuah pelanggaran terhadap premis dasar tentang tidak ada yang dibagikan).
Setiap kasus yang menarik melibatkan beberapa kombinasi sumber daya independen dan sumber daya bersama. Setiap komputer yang cukup modern (dan banyak yang sama sekali tidak modern) memiliki setidaknya beberapa kemampuan untuk melakukan setidaknya beberapa operasi independen secara bersamaan, dan hampir semua hal yang lebih canggih daripada MS-DOS telah memanfaatkannya untuk setidaknya beberapa derajat.
Pembagian yang bagus dan bersih antara "bersamaan" dan "paralel" yang orang suka menggambar tidak ada, dan hampir tidak pernah ada. Apa yang orang suka klasifikasikan sebagai "bersamaan" biasanya masih melibatkan paling tidak satu dan lebih banyak jenis eksekusi paralel. Apa yang mereka suka diklasifikasikan sebagai "paralel" sering melibatkan berbagi sumber daya dan (misalnya) satu proses memblokir eksekusi yang lain saat menggunakan sumber daya yang dibagi di antara keduanya.
Orang-orang yang mencoba menggambar perbedaan bersih antara "paralel" dan "bersamaan" hidup dalam fantasi komputer yang tidak pernah benar-benar ada.