Đồng thời và Song song
Cả hai phương thức đồng thời và song song đều được sử dụng liên quan đến các chương trình đa luồng nhưng có rất nhiều sự nhầm lẫn về sự giống và khác nhau giữa chúng. Câu hỏi lớn về vấn đề này: có phải là song song đồng thời hay không? Mặc dù cả hai thuật ngữ xuất hiện khá giống nhau nhưng câu trả lời cho câu hỏi trên là KHÔNG, đồng thời và song song không giống nhau. Bây giờ, nếu chúng không giống nhau thì sự khác biệt cơ bản giữa chúng là gì?
Nói một cách dễ hiểu, đồng thời đề cập đến việc quản lý quyền truy cập vào trạng thái chia sẻ từ các luồng khác nhau và mặt khác, song song đề cập đến việc sử dụng nhiều CPU hoặc lõi của nó để cải thiện hiệu suất của phần cứng.
Chi tiết về đồng tiền
Đồng thời là khi hai nhiệm vụ chồng chéo lên nhau trong quá trình thực thi. Nó có thể là một tình huống trong đó một ứng dụng đang thực hiện nhiều nhiệm vụ cùng một lúc. Chúng ta có thể hiểu nó theo sơ đồ; nhiều nhiệm vụ đang tiến triển cùng một lúc, như sau:
Mức độ đồng thời
Trong phần này, chúng ta sẽ thảo luận về ba cấp độ quan trọng của đồng thời về mặt lập trình -
Đồng tiền cấp thấp
Trong mức độ đồng thời này, có sử dụng rõ ràng các phép toán nguyên tử. Chúng tôi không thể sử dụng loại đồng thời như vậy để xây dựng ứng dụng, vì nó rất dễ xảy ra lỗi và khó gỡ lỗi. Ngay cả Python cũng không hỗ trợ loại đồng thời như vậy.
Đồng tiền cấp trung
Trong sự đồng thời này, không sử dụng các phép toán nguyên tử rõ ràng. Nó sử dụng các khóa rõ ràng. Python và các ngôn ngữ lập trình khác hỗ trợ loại đồng thời như vậy. Hầu hết các lập trình viên ứng dụng sử dụng đồng thời này.
Đồng tiền cấp cao
Trong sự đồng thời này, không sử dụng các phép toán nguyên tử rõ ràng cũng như các khóa rõ ràng. Python cóconcurrent.futures mô-đun để hỗ trợ loại đồng thời như vậy.
Thuộc tính của hệ thống đồng thời
Đối với một chương trình hoặc hệ thống đồng thời là đúng, một số thuộc tính phải được thỏa mãn bởi nó. Các thuộc tính liên quan đến việc chấm dứt hệ thống như sau:
Thuộc tính độ đúng
Thuộc tính độ đúng có nghĩa là chương trình hoặc hệ thống phải cung cấp câu trả lời đúng mong muốn. Để đơn giản, chúng ta có thể nói rằng hệ thống phải ánh xạ trạng thái chương trình bắt đầu đến trạng thái cuối cùng một cách chính xác.
Tài sản an toàn
Thuộc tính an toàn có nghĩa là chương trình hoặc hệ thống phải duy trì trong một “good” hoặc là “safe” trạng thái và không bao giờ làm bất cứ điều gì “bad”.
Tài sản sống
Thuộc tính này có nghĩa là một chương trình hoặc hệ thống phải “make progress” và nó sẽ đạt đến một số trạng thái mong muốn.
Tác nhân của hệ thống đồng thời
Đây là một thuộc tính chung của hệ thống đồng thời, trong đó có thể có nhiều quy trình và luồng chạy cùng một lúc để đạt được tiến độ trong các nhiệm vụ của riêng chúng. Các tiến trình và luồng này được gọi là các tác nhân của hệ thống đồng thời.
Tài nguyên của các hệ thống đồng thời
Các tác nhân phải sử dụng các tài nguyên như bộ nhớ, đĩa, máy in, v.v. để thực hiện nhiệm vụ của họ.
Một số quy tắc
Mọi hệ thống đồng thời phải có một bộ quy tắc để xác định loại nhiệm vụ được thực hiện bởi các tác nhân và thời gian cho mỗi loại. Các nhiệm vụ có thể là lấy khóa, chia sẻ bộ nhớ, sửa đổi trạng thái, v.v.
Rào cản của các hệ thống đồng thời
Trong khi triển khai các hệ thống đồng thời, người lập trình phải xem xét hai vấn đề quan trọng sau đây, có thể là rào cản của các hệ thống đồng thời -Chia sẻ dữ liệu
Một vấn đề quan trọng trong khi triển khai các hệ thống đồng thời là việc chia sẻ dữ liệu giữa nhiều luồng hoặc quy trình. Trên thực tế, lập trình viên phải đảm bảo rằng các khóa bảo vệ dữ liệu được chia sẻ để tất cả các quyền truy cập vào nó được tuần tự hóa và chỉ một luồng hoặc quy trình có thể truy cập dữ liệu được chia sẻ tại một thời điểm. Trong trường hợp, khi nhiều luồng hoặc quá trình đều cố gắng truy cập vào cùng một dữ liệu được chia sẻ thì không phải tất cả nhưng ít nhất một trong số chúng sẽ bị chặn và sẽ không hoạt động. Nói cách khác, chúng ta có thể nói rằng chúng ta chỉ có thể sử dụng một tiến trình hoặc một luồng tại một thời điểm khi khóa có hiệu lực. Có thể có một số giải pháp đơn giản để loại bỏ các rào cản nêu trên -
Hạn chế chia sẻ dữ liệu
Giải pháp đơn giản nhất là không chia sẻ bất kỳ dữ liệu có thể thay đổi nào. Trong trường hợp này, chúng tôi không cần sử dụng khóa rõ ràng và rào cản đồng thời do dữ liệu lẫn nhau sẽ được giải quyết.
Hỗ trợ cấu trúc dữ liệu
Nhiều khi các quá trình đồng thời cần truy cập cùng một dữ liệu cùng một lúc. Một giải pháp khác, ngoài việc sử dụng các khóa rõ ràng, là sử dụng cấu trúc dữ liệu hỗ trợ truy cập đồng thời. Ví dụ, chúng ta có thể sử dụngqueuemô-đun, cung cấp hàng đợi an toàn theo luồng. Chúng tôi cũng có thể sử dụngmultiprocessing.JoinableQueue các lớp cho đồng thời dựa trên đa xử lý.
Truyền dữ liệu bất biến
Đôi khi, cấu trúc dữ liệu mà chúng ta đang sử dụng, chẳng hạn như hàng đợi đồng thời, không phù hợp thì chúng ta có thể chuyển dữ liệu bất biến mà không cần khóa nó.
Truyền dữ liệu có thể thay đổi
Tiếp tục giải pháp trên, giả sử nếu yêu cầu chỉ truyền dữ liệu có thể thay đổi thay vì dữ liệu bất biến, thì chúng ta có thể chuyển dữ liệu có thể thay đổi được chỉ đọc.
Chia sẻ tài nguyên I / O
Một vấn đề quan trọng khác trong việc triển khai các hệ thống đồng thời là việc sử dụng các tài nguyên I / O theo các luồng hoặc quy trình. Sự cố phát sinh khi một luồng hoặc quá trình sử dụng I / O trong một thời gian dài như vậy và luồng khác đang ở chế độ chờ. Chúng ta có thể thấy loại rào cản như vậy khi làm việc với một ứng dụng I / O nặng. Nó có thể được hiểu với sự trợ giúp của một ví dụ, yêu cầu các trang từ trình duyệt web. Nó là một ứng dụng nặng. Ở đây, nếu tốc độ dữ liệu được yêu cầu chậm hơn tốc độ dữ liệu được sử dụng thì chúng ta có rào cản I / O trong hệ thống đồng thời của mình.
Tập lệnh Python sau đây là để yêu cầu một trang web và lấy thời gian mạng của chúng tôi để lấy trang được yêu cầu -
import urllib.request
import time
ts = time.time()
req = urllib.request.urlopen('http://www.tutorialspoint.com')
pageHtml = req.read()
te = time.time()
print("Page Fetching Time : {} Seconds".format (te-ts))
Sau khi thực hiện đoạn script trên, chúng ta có thể có được thời gian tìm nạp trang như hình bên dưới.
Đầu ra
Page Fetching Time: 1.0991398811340332 Seconds
Chúng ta có thể thấy rằng thời gian để tìm nạp trang là hơn một giây. Bây giờ điều gì xảy ra nếu chúng tôi muốn tìm nạp hàng nghìn trang web khác nhau, bạn có thể hiểu mạng của chúng tôi sẽ mất bao nhiêu thời gian.
Song song là gì?
Song song có thể được định nghĩa là nghệ thuật tách các nhiệm vụ thành các nhiệm vụ con có thể được xử lý đồng thời. Nó đối lập với đồng thời, như đã thảo luận ở trên, trong đó hai hoặc nhiều sự kiện xảy ra cùng một lúc. Chúng ta có thể hiểu nó theo sơ đồ; một nhiệm vụ được chia thành một số nhiệm vụ con có thể được xử lý song song, như sau:
Để có thêm ý tưởng về sự phân biệt giữa đồng thời và song song, hãy xem xét các điểm sau:
Đồng thời nhưng không song song
Một ứng dụng có thể đồng thời nhưng không song song có nghĩa là nó xử lý nhiều hơn một tác vụ cùng một lúc nhưng các tác vụ không được chia nhỏ thành các nhiệm vụ con.
Song song nhưng không đồng thời
Một ứng dụng có thể song song nhưng không đồng thời có nghĩa là nó chỉ hoạt động trên một nhiệm vụ tại một thời điểm và các tác vụ được chia thành các nhiệm vụ con có thể được xử lý song song.
Không song song cũng không đồng thời
Một ứng dụng có thể không song song hoặc đồng thời. Điều này có nghĩa là nó chỉ hoạt động trên một nhiệm vụ tại một thời điểm và nhiệm vụ không bao giờ được chia thành các nhiệm vụ con.
Cả song song và đồng thời
Một ứng dụng có thể vừa song song vừa đồng thời có nghĩa là nó vừa hoạt động trên nhiều tác vụ cùng một lúc và tác vụ được chia thành các nhiệm vụ con để thực hiện chúng song song.
Sự cần thiết của thuyết song song
Chúng ta có thể đạt được tính song song bằng cách phân phối các nhiệm vụ con giữa các lõi khác nhau của một CPU hoặc giữa nhiều máy tính được kết nối trong một mạng.
Hãy xem xét các điểm quan trọng sau để hiểu tại sao cần phải đạt được tính song song -
Thực thi mã hiệu quả
Với sự trợ giúp của song song, chúng tôi có thể chạy mã của mình một cách hiệu quả. Nó sẽ tiết kiệm thời gian của chúng tôi vì cùng một mã trong các phần đang chạy song song.
Nhanh hơn tính toán tuần tự
Tính toán tuần tự bị hạn chế bởi các yếu tố vật lý và thực tế do đó không thể có kết quả tính toán nhanh hơn. Mặt khác, vấn đề này được giải quyết bằng tính toán song song và cho chúng ta kết quả tính toán nhanh hơn so với tính toán tuần tự.
Thời gian thực hiện ít hơn
Xử lý song song làm giảm thời gian thực thi mã chương trình.
Nếu chúng ta nói về ví dụ thực tế về tính song song, thì card đồ họa của máy tính là ví dụ làm nổi bật sức mạnh thực sự của xử lý song song vì nó có hàng trăm lõi xử lý riêng lẻ hoạt động độc lập và có thể thực hiện cùng một lúc. Vì lý do này, chúng tôi cũng có thể chạy các ứng dụng và trò chơi cao cấp.
Hiểu biết về các bộ xử lý để thực hiện
Chúng ta biết về tính đồng thời, tính song song và sự khác biệt giữa chúng nhưng còn về hệ thống mà nó sẽ được triển khai. Rất cần sự hiểu biết về hệ thống mà chúng ta sẽ triển khai, bởi vì nó mang lại cho chúng ta lợi ích khi đưa ra quyết định sáng suốt trong khi thiết kế phần mềm. Chúng tôi có hai loại bộ xử lý sau:
Bộ xử lý lõi đơn
Bộ xử lý lõi đơn có khả năng thực thi một luồng tại bất kỳ thời điểm nào. Các bộ xử lý này sử dụngcontext switchingđể lưu trữ tất cả thông tin cần thiết cho một chuỗi tại một thời điểm cụ thể và sau đó khôi phục thông tin sau đó. Cơ chế chuyển đổi ngữ cảnh giúp chúng tôi đạt được tiến bộ trên một số luồng trong một giây nhất định và có vẻ như hệ thống đang làm việc trên nhiều thứ.
Bộ vi xử lý lõi đơn đi kèm với nhiều ưu điểm. Các bộ xử lý này yêu cầu ít năng lượng hơn và không có giao thức giao tiếp phức tạp giữa nhiều lõi. Mặt khác, tốc độ của bộ vi xử lý lõi đơn bị hạn chế và nó không thích hợp cho các ứng dụng lớn hơn.
Bộ xử lý đa lõi
Bộ xử lý đa lõi có nhiều đơn vị xử lý độc lập còn được gọi là cores.
Các bộ xử lý như vậy không cần cơ chế chuyển đổi ngữ cảnh vì mỗi lõi chứa mọi thứ nó cần để thực hiện một chuỗi các lệnh được lưu trữ.
Chu trình tìm nạp-giải mã-thực thi
Các lõi của bộ xử lý đa lõi tuân theo một chu kỳ để thực thi. Chu kỳ này được gọi làFetch-Decode-Executeđi xe đạp. Nó bao gồm các bước sau:
Tìm nạp
Đây là bước đầu tiên của chu trình, bao gồm việc tìm nạp các lệnh từ bộ nhớ chương trình.
Giải mã
Các hướng dẫn được tải gần đây sẽ được chuyển đổi thành một loạt các tín hiệu sẽ kích hoạt các bộ phận khác của CPU.
Hành hình
Đây là bước cuối cùng trong đó các lệnh được tìm nạp và giải mã sẽ được thực thi. Kết quả thực thi sẽ được lưu trữ trong thanh ghi CPU.
Một lợi thế ở đây là việc thực thi trong bộ xử lý đa lõi nhanh hơn so với bộ xử lý đơn lõi. Nó phù hợp cho các ứng dụng lớn hơn. Mặt khác, giao thức giao tiếp phức tạp giữa nhiều lõi là một vấn đề. Nhiều lõi yêu cầu nhiều năng lượng hơn bộ xử lý đơn lõi.