Làm cách nào tôi có thể có 1805 luồng khi tôi chỉ có 4 CPU ảo?


10

Tôi đã tự hỏi nếu ai đó có thể giải thích cho tôi làm thế nào trong Trình giám sát hoạt động của tôi thì nó nói rằng tôi hiện có 1805 chủ đề Ảnh chụp màn hình của OS X Activity Monitor

Nhưng tôi chỉ có 4 lõi ảo trên máy tính của mình (điều đó có nghĩa là tôi chỉ có thể có 4 luồng). Số lượng luồng có nghĩa là tất cả các luồng đang được xử lý bởi CPU khi chúng quyết định thực hiện luồng nào?

EDIT: Lý do tôi nghĩ rằng chỉ có thể có 4 luồng trên máy của tôi xuất phát từ câu trả lời này . Tôi tin rằng sự hiểu lầm của tôi bắt nguồn từ từ 'chủ đề' được sử dụng trong một bối cảnh khác.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
bmike

Câu trả lời:


24

Lập kế hoạch

1.805 chủ đề của bạn không chạy cùng một lúc . Họ đánh đổi. Một lõi chạy một chút của luồng, sau đó đặt nó sang một bên để thực hiện một chút của luồng khác. Các lõi khác làm tương tự. Tròn và tròn, các chủ đề thực hiện một chút tại một thời điểm, không phải tất cả cùng một lúc.

Một trách nhiệm chính của hệ điều hành (Darwin và macOS) là lập lịch cho luồng nào sẽ được thực hiện trên lõi nào trong bao lâu.

Nhiều chủ đề không có việc phải làm, và vì vậy không hoạt động và không được lên lịch. Tương tự, nhiều luồng có thể đang chờ trên một số tài nguyên như dữ liệu được truy xuất từ ​​bộ lưu trữ hoặc kết nối mạng cần hoàn thành hoặc dữ liệu được tải từ cơ sở dữ liệu. Hầu như không có gì để làm ngoài việc kiểm tra trạng thái của tài nguyên đang chờ, các luồng như vậy được lên lịch khá ngắn gọn nếu có.

Lập trình viên ứng dụng có thể hỗ trợ thao tác lập lịch trình này bằng cách ngủ chủ đề của cô ấy trong một khoảng thời gian nhất định khi cô ấy biết việc chờ đợi tài nguyên bên ngoài sẽ mất một thời gian. Và nếu chạy một vòng lặp chặt chẽ, chặt chẽ mà không cần phải chờ đợi tài nguyên bên ngoài, lập trình viên có thể chèn một cuộc gọi để tình nguyện được đặt sang một bên một cách ngắn gọn để không làm hỏng lõi và do đó cho phép các luồng khác thực thi.

Để biết thêm chi tiết, xem trang Wikipedia để biết đa luồng .

Đồng thời đa luồng

Đối với Câu hỏi được liên kết của bạn , chủ đề thực sự giống như ở đây.

Một vấn đề là chi phí chuyển đổi giữa các luồng khi được HĐH lên lịch. Có một chi phí đáng kể về thời gian để dỡ bỏ các hướng dẫn và dữ liệu của luồng hiện tại khỏi lõi và sau đó tải các hướng dẫn và dữ liệu của luồng theo lịch trình tiếp theo. Một phần công việc của hệ điều hành là cố gắng thông minh trong việc lên lịch cho các luồng như để tối ưu hóa xung quanh chi phí này.

Một số nhà sản xuất CPU đã phát triển công nghệ để cắt giảm thời gian này để giúp chuyển đổi giữa một cặp luồng nhanh hơn nhiều. Intel gọi công nghệ của họ là Hyper-Threading . Được biết đến rộng rãi như là đa luồng đồng thời (SMT) .

Mặc dù cặp luồng không thực sự thực hiện đồng thời, việc chuyển đổi diễn ra suôn sẻ và nhanh chóng đến mức cả hai luồng dường như gần như đồng thời. Điều này hoạt động tốt đến mức mỗi lõi thể hiện chính nó như một cặp lõi ảo cho HĐH. Vì vậy, một CPU kích hoạt SMT có bốn lõi vật lý, ví dụ, sẽ tự trình bày cho HĐH dưới dạng CPU tám lõi.

Mặc dù tối ưu hóa này, vẫn có một số chi phí để chuyển đổi giữa các lõi ảo như vậy. Quá nhiều luồng xử lý nhiều CPU, tất cả việc theo dõi thời gian thực hiện được lên lịch trên lõi có thể làm cho hệ thống hoạt động kém hiệu quả, không có luồng nào làm được nhiều việc. Giống như ba quả bóng trên một sân chơi được chia sẻ giữa chín đứa trẻ, so với việc chia sẻ giữa chín trăm đứa trẻ mà không một đứa trẻ nào thực sự có được thời gian chơi nghiêm túc với một quả bóng.

Vì vậy, có một tùy chọn trong phần sụn CPU, trong đó một sysadmin có thể ném công tắc vào máy để vô hiệu hóa SMT nếu cô ấy quyết định nó sẽ có lợi cho người dùng của cô ấy chạy một ứng dụng bị ràng buộc CPU bất thường với rất ít cơ hội để tạm dừng.

Trong trường hợp như vậy, chúng tôi trở lại Câu hỏi ban đầu của bạn: Trong tình huống đặc biệt này, bạn thực sự muốn hạn chế các hoạt động để không có nhiều luồng siêu hoạt động này hơn bạn có lõi vật lý. Nhưng hãy để tôi nhắc lại: đây là một tình huống cực kỳ bất thường có thể xảy ra trong một cái gì đó giống như một dự án khủng hoảng dữ liệu khoa học chuyên ngành nhưng hầu như sẽ không bao giờ áp dụng cho các kịch bản kinh doanh / doanh nghiệp / doanh nghiệp phổ biến.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
bmike

Ngoài ra, không ai thực hiện yield()các cuộc gọi hệ thống trong các luồng chuyên sâu về CPU của họ (trừ khi đó là mã kế thừa từ đa tác vụ hợp tác trên MacOS cổ điển). Sắp xếp lại đa tác vụ trước khi một luồng sử dụng hết thời gian của nó.
Peter Cordes

Mô tả của bạn về siêu phân luồng là sai. Chủ đề phần cứng! = Chủ đề phần mềm, chúng là bối cảnh thực thi / lõi logic. Cả hai lõi logic trên lõi vật lý thực sự chạy các hướng dẫn của chúng cùng một lúc. Mặt trước xen kẽ giữa các luồng (mỗi chu kỳ), nhưng lõi thực thi không theo thứ tự có thể thực thi các lệnh / uops từ cả hai luồng trong cùng một chu kỳ. Điều này phơi bày sự song song ở mức hướng dẫn từ hai luồng cho thực thi OoO để giữ tốt hơn các đơn vị thực thi được cung cấp với công việc (về cơ bản đây là điểm của SMT). Đó không chỉ là "tối ưu hóa chuyển đổi ngữ cảnh".
Peter Cordes


7

Ngày xưa - bộ nhớ không được ảo hóa hoặc được bảo vệ và bất kỳ mã nào cũng có thể ghi ở bất cứ đâu. Trong những ngày đó, một chủ đề cho một thiết kế CPU có ý nghĩa. Trong những thập kỷ kể từ đó, bộ nhớ đầu tiên được bảo vệ và sau đó được ảo hóa. Hãy nghĩ về các luồng như các lõi ảo - một lời hứa rằng tại một thời điểm nào đó khi dữ liệu và mã của bạn đã sẵn sàng, luồng đó sẽ được đẩy ( hoặc được lên kế hoạch như các kỹ sư và nhà toán học PHD thực hiện nghiên cứu về thuật toán lập lịch gọi nó ) vào CPU thực tế làm công việc thực tế.

nhập mô tả hình ảnh ở đây

Bây giờ - do mức độ khác biệt về thời gian - CPU và bộ đệm hoạt động quá nhanh so với việc lấy dữ liệu từ bộ lưu trữ hoặc mạng - mà hàng ngàn luồng có thể đến và đi trong khi một luồng đang chờ www.google.com cung cấp gói hoặc hai dữ liệu vì vậy đó là lý do tại sao bạn thấy nhiều luồng hơn CPU thực tế.

Nếu bạn chuyển đổi các thao tác luồng xảy ra theo thang thời gian đen / xanh và chuyển đổi chúng thành một giây = 1 ns, thì những điều chúng tôi quan tâm giống như đĩa IO mất 100 micro giây giống như 4 ngày và chuyến đi vòng 200 giây trên internet là một Trì hoãn 20 năm nếu bạn đếm giây trên thang thời gian CPU. Giống như nhiều sức mạnh của mười bài tập , trong hầu hết các trường hợp - CPU không hoạt động trong "tháng" chờ đợi công việc có ý nghĩa từ một thế giới bên ngoài rất, rất chậm.

Không có gì có vẻ không ổn trong hình ảnh bạn đã đăng vì vậy có lẽ chúng tôi hiểu nhầm những gì bạn đang nhận được bằng cách tự hỏi về chủ đề.

Nếu bạn nhấp chuột phải (nhấp chuột điều khiển) vào các chủ đề từ trong hàng tiêu đề ở trên cùng, hãy thêm trạng thái của ứng dụng và bạn sẽ thấy hầu hết các chủ đề có thể không hoạt động, đang ngủ, không chạy tại bất kỳ thời điểm nào.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
bmike

1

Bạn không hỏi câu hỏi cơ bản hơn, "Làm thế nào tôi có thể có 290 quy trình khi CPU của tôi chỉ có bốn lõi?" Câu trả lời này là một chút lịch sử, có thể giúp bạn hiểu được bức tranh lớn, mặc dù câu hỏi cụ thể đã được trả lời. Như vậy, tôi sẽ không cung cấp phiên bản TL; DR.

Ngày xửa ngày xưa (nghĩ rằng, thập niên 1950), máy tính chỉ có thể làm một việc một lúc. Chúng rất đắt, chứa đầy các phòng và chúng tôi cần một cách để sử dụng chúng hiệu quả bằng cách chia sẻ chúng giữa nhiều người. Cách đầu tiên để thực hiện việc này là xử lý hàng loạt , trong đó người dùng sẽ gửi các tác vụ đến máy tính và họ sẽ được xếp hàng, thực hiện lần lượt từng cái một và kết quả sẽ được gửi lại cho người dùng. Điều đó không sao nhưng điều đó có nghĩa là, nếu bạn muốn thực hiện một phép tính sẽ mất vài ngày, không ai khác có thể sử dụng máy tính trong thời gian đó.

Sự đổi mới tiếp theo (nghĩ, những năm 1960 của thập niên 70) là chia sẻ thời gian . Bây giờ, thay vì thực thi toàn bộ một tác vụ, sau đó là toàn bộ tác vụ tiếp theo, máy tính sẽ thực thi một chút của một tác vụ, sau đó tạm dừng nó và thực hiện một chút của tác vụ tiếp theo, v.v. Do đó, máy tính sẽ tạo ấn tượng rằng nó đang thực hiện đồng thời nhiều quy trình. Ưu điểm tuyệt vời của việc này là bây giờ bạn có thể chạy một phép tính sẽ mất một vài ngày và mặc dù bây giờ sẽ còn lâu hơn nữa, vì nó cứ bị gián đoạn, những người khác vẫn có thể sử dụng máy trong thời gian đó.

Tất cả điều này là cho các máy tính kiểu máy tính lớn. Khi máy tính cá nhân bắt đầu trở nên phổ biến, ban đầu chúng không mạnh lắm và, vì chúng là cá nhân nên chúng chỉ có thể làm một việc & nbdp; - chạy một ứng dụng - ngay lập tức (nghĩ, những năm 1980). Nhưng, khi chúng trở nên mạnh mẽ hơn (nghĩ rằng, những năm 1990 đến nay), mọi người cũng muốn máy tính cá nhân của họ chia sẻ thời gian.

Vì vậy, chúng tôi đã kết thúc với các máy tính cá nhân tạo ra ảo tưởng về việc chạy đồng thời nhiều quy trình bằng cách thực sự chạy chúng cùng một lúc trong thời gian ngắn và sau đó tạm dừng chúng. Các chủ đề về cơ bản là giống nhau: cuối cùng, mọi người thậm chí muốn các quy trình riêng lẻ đưa ra ảo tưởng làm nhiều việc cùng một lúc. Đầu tiên, người viết ứng dụng phải tự xử lý việc đó: dành một chút thời gian để cập nhật đồ họa, tạm dừng điều đó, dành một chút trong khi tính toán, tạm dừng điều đó, dành một chút trong khi làm việc khác, ...

Tuy nhiên, hệ điều hành đã rất tốt trong việc quản lý nhiều quy trình, nên mở rộng nó để quản lý các quy trình phụ này, được gọi là các luồng. Vì vậy, bây giờ, chúng ta có một mô hình trong đó mọi quy trình (hoặc ứng dụng) chứa ít nhất một luồng, nhưng một số có chứa một vài hoặc nhiều. Mỗi trong số các chủ đề này tương ứng với một nhiệm vụ con độc lập.

Nhưng, ở cấp cao nhất, CPU vẫn chỉ tạo ảo giác rằng tất cả các luồng này đều chạy cùng một lúc. Trong thực tế, nó chạy một chút, tạm dừng nó, chọn một cái khác để chạy một chút, v.v. Ngoại trừ việc CPU hiện đại có thể chạy nhiều luồng cùng một lúc. Vì vậy, trong thực tế, hệ điều hành đang chơi trò chơi "chạy một chút, tạm dừng, chạy thứ khác một chút, tạm dừng" trên tất cả các lõi cùng một lúc. Vì vậy, bạn có thể có nhiều chủ đề như bạn (và nhà thiết kế ứng dụng của bạn) muốn, nhưng tại bất kỳ thời điểm nào, tất cả trừ một vài trong số chúng sẽ thực sự bị tạm dừng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.