Chúng là hai cụm từ mô tả cùng một điều từ các quan điểm khác nhau (rất nhẹ). Lập trình song song là mô tả tình huống theo quan điểm của phần cứng - có ít nhất hai bộ xử lý (có thể trong một gói vật lý) hoạt động song song với một vấn đề. Lập trình đồng thời là mô tả nhiều thứ hơn từ quan điểm của phần mềm - hai hoặc nhiều hành động có thể xảy ra cùng một lúc (đồng thời).
Vấn đề ở đây là mọi người đang cố gắng sử dụng hai cụm từ để phân biệt rõ ràng khi không có gì thực sự tồn tại. Thực tế là đường phân chia mà họ đang cố vẽ đã mờ nhạt và không rõ ràng trong nhiều thập kỷ, và đã trở nên không rõ ràng hơn theo thời gian.
Điều họ đang cố gắng thảo luận là thực tế là ngày xưa, hầu hết các máy tính chỉ có một CPU. Khi bạn thực hiện nhiều quy trình (hoặc luồng) trên một CPU đó, CPU chỉ thực sự thực hiện một lệnh từ một trong các luồng đó tại một thời điểm. Sự xuất hiện của đồng thời là một ảo ảnh - CPU chuyển đổi giữa các lệnh thực thi từ các luồng khác nhau đủ nhanh để nhận thức của con người (mà bất cứ thứ gì dưới 100 ms hoặc trông như vậy ngay lập tức) có vẻ như nó đang làm nhiều việc cùng một lúc.
Sự tương phản rõ ràng với điều này là một máy tính có nhiều CPU hoặc CPU có nhiều lõi, vì vậy máy đang thực hiện các hướng dẫn từ nhiều luồng và / hoặc các tiến trình cùng một lúc; thực thi mã một không thể / không có bất kỳ ảnh hưởng nào đến việc thực thi mã khác.
Bây giờ vấn đề: một sự phân biệt rõ ràng như vậy gần như không bao giờ tồn tại. Các nhà thiết kế máy tính thực sự khá thông minh, vì vậy họ đã nhận thấy từ lâu rằng (ví dụ) khi bạn cần đọc một số dữ liệu từ một thiết bị I / O như đĩa, phải mất một thời gian dài (về chu kỳ CPU) để hoàn thành. Thay vì để CPU nhàn rỗi trong khi điều đó xảy ra, họ đã tìm ra nhiều cách khác nhau để cho một tiến trình / luồng thực hiện một yêu cầu I / O và để mã từ một số tiến trình / luồng khác thực thi trên CPU trong khi yêu cầu I / O hoàn thành.
Vì vậy, rất lâu trước khi CPU đa lõi trở thành chuẩn mực, chúng tôi đã có các hoạt động từ nhiều luồng xảy ra song song.
Đó chỉ là phần nổi của tảng băng. Nhiều thập kỷ trước, máy tính cũng bắt đầu cung cấp một mức độ song song khác. Một lần nữa, là những người khá thông minh, các nhà thiết kế máy tính nhận thấy rằng trong rất nhiều trường hợp, họ có các hướng dẫn không ảnh hưởng lẫn nhau, do đó có thể thực hiện nhiều hơn một lệnh từ cùng một luồng. Một ví dụ ban đầu đã trở nên khá nổi tiếng là Control Data 6600. Đây là (máy tính khá rộng) là máy tính nhanh nhất trên trái đất khi được giới thiệu vào năm 1964 - và phần lớn kiến trúc cơ bản vẫn được sử dụng cho đến ngày nay. Nó theo dõi các tài nguyên được sử dụng bởi mỗi hướng dẫn và có một tập hợp các đơn vị thực thi thực thi các lệnh ngay khi tài nguyên mà chúng phụ thuộc có sẵn, rất giống với thiết kế của hầu hết các bộ xử lý Intel / AMD gần đây.
Nhưng (như quảng cáo thường nói) chờ đợi - đó không phải là tất cả. Vẫn còn một yếu tố thiết kế khác để thêm sự nhầm lẫn. Nó được đặt cho khá nhiều tên khác nhau (ví dụ: "Siêu phân luồng", "SMT", "CMP"), nhưng tất cả chúng đều đề cập đến cùng một ý tưởng cơ bản: CPU có thể thực thi đồng thời nhiều luồng, sử dụng kết hợp một số tài nguyên là độc lập cho mỗi luồng và một số tài nguyên được chia sẻ giữa các luồng. Trong một trường hợp điển hình, điều này được kết hợp với song song mức hướng dẫn được nêu ở trên. Để làm điều đó, chúng tôi có hai (hoặc nhiều) bộ đăng ký kiến trúc. Sau đó, chúng tôi có một bộ các đơn vị thực thi có thể thực hiện các hướng dẫn ngay khi các tài nguyên cần thiết có sẵn.
Sau đó, tất nhiên, chúng ta có được các hệ thống hiện đại với nhiều lõi. Ở đây mọi thứ là hiển nhiên, phải không? Hiện tại chúng tôi có các lõi riêng biệt N (khoảng từ 2 đến 256 hoặc hơn), tất cả đều có thể thực hiện các lệnh cùng một lúc, vì vậy chúng tôi có trường hợp song song rõ ràng - thực hiện các lệnh trong một quy trình / luồng không ' t ảnh hưởng đến hướng dẫn thực hiện trong một hướng dẫn khác.
Vâng, loại. Ngay cả ở đây, chúng ta có một số tài nguyên độc lập (thanh ghi, đơn vị thực thi, ít nhất một mức bộ đệm) và một số tài nguyên được chia sẻ (thường là ít nhất là mức thấp nhất của bộ đệm, và chắc chắn là bộ điều khiển bộ nhớ và băng thông vào bộ nhớ).
Tóm lại: các kịch bản đơn giản mà mọi người muốn tương phản giữa các tài nguyên được chia sẻ và tài nguyên độc lập hầu như không bao giờ xảy ra trong cuộc sống thực. Với tất cả các tài nguyên được chia sẻ, chúng tôi kết thúc với một thứ như MS-DOS, nơi chúng tôi chỉ có thể chạy một chương trình tại một thời điểm và chúng tôi phải dừng chạy một chương trình trước khi chúng tôi có thể chạy chương trình khác. Với tài nguyên hoàn toàn độc lập, chúng tôi có N máy tính chạy MS-DOS (thậm chí không có mạng để kết nối chúng) mà không có khả năng chia sẻ bất cứ thứ gì giữa chúng (vì nếu chúng tôi thậm chí có thể chia sẻ một tệp, đó là tài nguyên được chia sẻ, vi phạm các tiền đề cơ bản của không có gì được chia sẻ).
Mỗi trường hợp thú vị liên quan đến một số sự kết hợp của các tài nguyên độc lập và tài nguyên được chia sẻ. Mọi máy tính hiện đại hợp lý (và rất nhiều máy tính hiện đại) đều có ít nhất một số khả năng để thực hiện ít nhất một vài hoạt động độc lập đồng thời, và hầu như mọi thứ phức tạp hơn MS-DOS đã tận dụng điều đó ít nhất một mức độ nào đó
Sự phân chia rõ ràng, tốt đẹp giữa "đồng thời" và "song song" mà mọi người muốn vẽ chỉ không tồn tại và gần như không bao giờ có. Những gì mọi người muốn phân loại là "đồng thời" thường vẫn liên quan đến ít nhất một và thường là nhiều loại thực thi song song khác nhau. Những gì họ muốn phân loại là "song song" thường liên quan đến việc chia sẻ tài nguyên và (ví dụ) một quy trình chặn thực thi của người khác trong khi sử dụng tài nguyên được chia sẻ giữa hai tài nguyên.
Mọi người đang cố gắng phân biệt rõ ràng giữa "song song" và "đồng thời" đang sống trong một ảo mộng về những chiếc máy tính chưa bao giờ thực sự tồn tại.