Quá trình CPU nhàn rỗi làm gì?


73

Nhìn vào nguồn của stracetôi thấy việc sử dụng cờ nhân bản CLONE_IDLETASKđược mô tả ở đó là:

#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */

Sau khi nhìn sâu hơn vào nó, tôi thấy rằng, mặc dù cờ đó không được bao phủ bởi man clonenó thực sự được sử dụng bởi kernel trong quá trình khởi động để tạo các tiến trình nhàn rỗi (tất cả đều phải có PID 0) cho mỗi CPU trên máy. tức là một máy có 8 CPU sẽ có ít nhất 7 (xem câu hỏi bên dưới) các quá trình "chạy" như vậy (ghi chú trích dẫn).

Bây giờ, điều này dẫn tôi đến một vài câu hỏi về quá trình "nhàn rỗi" đó thực sự làm gì. Giả định của tôi là nó thực hiện hoạt động NOP liên tục cho đến khi khung thời gian của nó kết thúc và kernel gán một quy trình thực sự để chạy hoặc gán quy trình nhàn rỗi một lần nữa (nếu CPU không được sử dụng). Tuy nhiên, đó là một phỏng đoán hoàn chỉnh. Vì thế:

  1. Trên một máy có 8 CPU sẽ tạo ra 7 tiến trình nhàn rỗi như vậy? (và một CPU sẽ được giữ bởi chính kernel trong khi không hoạt động trong không gian người dùng?)

  2. Là quá trình nhàn rỗi thực sự chỉ là một dòng vô hạn của các hoạt động NOP? (hoặc một vòng lặp làm như vậy).

  3. Việc sử dụng CPU (giả sử uptime) có được tính đơn giản bằng quá trình nhàn rỗi trên CPU và thời gian không có trong một khoảng thời gian nhất định không?


PS Có khả năng rất nhiều câu hỏi này là do thực tế là tôi không hiểu đầy đủ về cách thức hoạt động của CPU. tức là tôi hiểu lắp ráp, khung thời gian và ngắt nhưng tôi không biết làm thế nào, ví dụ, CPU có thể sử dụng nhiều hay ít năng lượng tùy thuộc vào những gì nó đang thực thi. Tôi sẽ biết ơn nếu ai đó cũng có thể khai sáng cho tôi về điều đó.


17
Tôi đã phải chống lại sự cám dỗ chỉ viết "Không có gì" khi tôi thấy tiêu đề.
Vality

4
Hầu hết các CPU hiện đại sẽ tự động giảm tốc độ xung nhịp và mức tiêu thụ năng lượng của chúng khi chạy không tải hoặc ở mức tải thấp ( thang đo tần số động , ví dụ SpeedStep cho CPU của Intel). Nếu bạn ép xung CPU, nó thường sẽ vô hiệu hóa hành vi này, khiến CPU duy trì tốc độ xung nhịp tối đa ngay cả khi không hoạt động.
Nat

2
Xem thêm "Trạng thái nguồn ACPI": có nhiều cách khác nhau để bộ xử lý có thể dừng thực thi các hướng dẫn nhưng vẫn có thể đánh thức được.
pjc50

Câu trả lời:


85

Nhiệm vụ nhàn rỗi được sử dụng cho kế toán quy trình, và cũng để giảm tiêu thụ năng lượng. Trong Linux, một tác vụ nhàn rỗi được tạo cho mọi bộ xử lý và bị khóa với bộ xử lý đó; Bất cứ khi nào không có quá trình khác để chạy trên CPU đó, tác vụ nhàn rỗi được lên lịch. Thời gian dành cho các tác vụ nhàn rỗi xuất hiện dưới dạng Thời gian nhàn rỗi trong các công cụ như top. (Thời gian hoạt động được tính khác nhau.)

Unix dường như luôn có một vòng lặp nhàn rỗi nào đó (nhưng không nhất thiết phải là một nhiệm vụ nhàn rỗi thực sự, xem câu trả lời của Gilles ), và ngay cả trong phiên bản V1, nó đã sử dụng một WAITlệnh dừng bộ xử lý cho đến khi xảy ra gián đoạn làm gián đoạn"). Một số hệ điều hành khác sử dụng các vòng lặp bận rộn, đặc biệt là DOS, OS / 2 và các phiên bản đầu tiên của Windows. Đã khá lâu rồi, các CPU đã sử dụng loại hướng dẫn này chờ đợi để giảm mức tiêu thụ năng lượng và sản xuất nhiệt. Bạn có thể thấy các triển khai khác nhau của các tác vụ nhàn rỗi, ví dụ như trong arch/x86/kernel/process.cnhân Linux: công việc cơ bản chỉ gọiHLT, dừng bộ xử lý cho đến khi xảy ra gián đoạn (và cho phép chế độ tiết kiệm năng lượng C1), các cài đặt khác xử lý các lỗi hoặc không hiệu quả khác nhau ( ví dụ: sử dụng MWAITthay vì HLTtrên một số CPU).

Tất cả điều này hoàn toàn tách biệt với trạng thái nhàn rỗi trong các quy trình, khi họ đang chờ đợi một sự kiện (I / O, v.v.).


3
Heh, tôi thấy nó bây giờ, cảm ơn. play_dead()là một cái tên dễ nhớ để thực hiện HALT. Sẽ không có rủi ro khi gửi HALT tới mọi CPU và do đó bị treo? (tức là đạt được tình huống đó, HALT mọi CPU, sẽ là một lỗi trong kernel đúng không?)
grochmal

30
CPU thức dậy từ HALT thông qua một ngắt.
Johan Myréen

1
@ JohanMyréen - Thật tuyệt, điều đó có ý nghĩa. Trong trường hợp như vậy, ngay cả một IRQ bị gián đoạn từ một thiết bị đầu vào cũng sẽ đánh thức nó trở lại. Cảm ơn.
hóa dầu

15
Hay đáng tin cậy hơn, bộ đếm thời gian bị gián đoạn ... (Xử lý vô dụng là một ấm cá khác.)
Stephen Kitt

3
@EJP thực sự, đó là một hướng dẫn khá phổ biến, mặc dù nó có các tên khác nhau trong các kiến ​​trúc khác nhau.
user253751

50

Trong thiết kế sách giáo khoa của bộ lập lịch quy trình, nếu bộ lập lịch không có bất kỳ quy trình nào để lên lịch (tức là nếu tất cả các quy trình bị chặn, chờ đầu vào), thì bộ lập lịch sẽ chờ ngắt bộ xử lý. Ngắt có thể chỉ ra đầu vào từ một thiết bị ngoại vi (hành động của người dùng, gói mạng, đã đọc xong từ đĩa, v.v.) hoặc có thể là một ngắt hẹn giờ kích hoạt bộ định thời trong một tiến trình.

Bộ lập lịch của Linux không có mã đặc biệt cho trường hợp không cần làm gì. Thay vào đó, nó mã hóa trường hợp không cần làm như một quy trình đặc biệt, quy trình nhàn rỗi. Quá trình nhàn rỗi chỉ được lên lịch khi không có quy trình nào khác có thể lập lịch biểu (nó thực sự có mức độ ưu tiên thấp vô cùng). Quá trình nhàn rỗi trên thực tế là một phần của kernel: đó là một luồng kernel, tức là một luồng thực thi mã trong kernel, thay vì code trong một process. (Chính xác hơn, có một luồng như vậy cho mỗi CPU.) Khi quá trình nhàn rỗi chạy, nó thực hiện thao tác chờ-ngắt.

Làm thế nào chờ đợi cho hoạt động ngắt phụ thuộc vào khả năng của bộ xử lý. Với thiết kế bộ xử lý cơ bản nhất, đó chỉ là một vòng lặp bận rộn -

nothing:
    goto nothing

Bộ xử lý tiếp tục chạy một lệnh nhánh, điều này không thực hiện được gì. Hầu hết các hệ điều hành hiện đại không làm điều này trừ khi chúng chạy trên bộ xử lý, nơi không có gì tốt hơn và hầu hết các bộ xử lý đều có thứ gì đó tốt hơn. Thay vì tiêu tốn năng lượng, không làm gì ngoài việc sưởi ấm căn phòng, lý tưởng nhất là nên tắt bộ xử lý. Vì vậy, kernel chạy mã lệnh cho bộ xử lý tự tắt hoặc ít nhất là tắt hầu hết bộ xử lý. Phải có ít nhất một phần nhỏ được bật nguồn, bộ điều khiển ngắt. Khi một thiết bị ngoại vi kích hoạt ngắt, bộ điều khiển ngắt sẽ gửi tín hiệu đánh thức đến bộ xử lý chính (một phần) của bộ xử lý.

Trong thực tế, các CPU hiện đại như Intel / AMD và ARM có nhiều cài đặt quản lý năng lượng phức tạp. HĐH có thể ước tính thời gian bộ xử lý sẽ ở chế độ không tải và sẽ chọn các chế độ năng lượng thấp khác nhau tùy thuộc vào điều này. Các chế độ cung cấp các thỏa hiệp khác nhau giữa việc sử dụng năng lượng khi không sử dụng và thời gian cần thiết để vào và thoát khỏi chế độ không tải. Trên một số bộ xử lý, HĐH cũng có thể hạ thấp tốc độ xung nhịp của bộ xử lý khi thấy rằng các tiến trình không tiêu tốn nhiều thời gian của CPU.


5
Lưu ý rằng ngay cả các CPU nhúng rất cơ bản nhất như vi điều khiển dựa trên AVR cũng có lệnh WFI (Chờ ngắt), mặc dù lệnh đó có thể tương đương với NOP tùy thuộc vào mô hình chính xác.
Jonas Schäfer

@JonasWielicki Tôi nghĩ rằng bạn thường chỉ đi vào một vòng lặp chặt chẽ nếu bạn không có gì để làm, hoặc bạn có thể rơi vào trạng thái năng lượng thấp và chờ đợi sự gián đoạn để loại bạn ra khỏi nó (trạng thái năng lượng thấp hơn thường đòi hỏi nhiều hơn " kim loại "ngắt).
Nick T

1
@JonasWielicki Architectures được thiết kế cho các hệ thống nhúng quan tâm đến việc quản lý năng lượng vì vậy WFI rất quan trọng ở đó. Nhiều kiến ​​trúc cũ không có điều đó. Kiến trúc 8086 ban đầu không, AFAIR. 68k có WFI không? Đây có phải là một tính năng tiêu chuẩn trên MIPS? Sự quen thuộc của tôi với lập trình cấp thấp chủ yếu là trên ARM, trong đó tiêu thụ điện năng thấp là vấn đề tất nhiên và WFI chỉ là phần nổi của tảng băng quản lý năng lượng.
Gilles

1
@Gilles 8086 đã có một hướng dẫn tạm dừng. Xem en.m.wikipedia.org/wiki/HLT_(x86_in cản) Hướng dẫn chỉ bao gồm chức năng tiết kiệm năng lượng kể từ 80486 DX4. Nhìn lại lịch sử, HLT đã có từ năm 8080 và xuất phát (như Z80).
pabouk

1
@pabouk HLTcó thể giảm sức mạnh cho các biến thể SL của 386 và 486, trước khi DX4 xuất hiện (bài viết trên Wikipedia không chính xác).
Stephen Kitt

0

Không, một tác vụ nhàn rỗi không lãng phí chu kỳ CPU. Bộ lập lịch đơn giản là không chọn một quá trình nhàn rỗi để thực hiện. Một quá trình nhàn rỗi đang chờ một sự kiện nào đó xảy ra để nó có thể tiếp tục. Ví dụ, nó có thể chờ đầu vào trong một read()cuộc gọi hệ thống.

Nhân tiện, kernel không phải là một quá trình riêng biệt. Mã hạt nhân luôn được thực thi trong ngữ cảnh của một tiến trình (tốt, ngoại trừ trường hợp đặc biệt của luồng nhân), do đó không đúng khi nói "và một CPU sẽ được giữ bởi chính hạt nhân trong khi không có hoạt động của không gian người dùng".


3
Hmmm ... Tôi không nghĩ đó là loại quy trình nhàn rỗi được tạo bởi CLONE_IDLETASK. Nếu không thì nó hoàn toàn không cần phải tạo, tức là bộ lập lịch đã bỏ qua các tiến trình nhàn rỗi kernel trên CPU, nó sẽ không cần tạo bất kỳ quy trình nào cho chúng trong khi khởi động. (DW không phải là của tôi mặc dù :))
grochmal

Một chút googling tiết lộ rằng CLONE_IDLETASK là một cờ nội bộ hạt nhân được giới thiệu xung quanh phiên bản kernel 2.5,14 vào năm 2002 và sau đó bị xóa vào năm 2004.
Johan Myréen

"an" quá trình nhàn rỗi nhưng không phải là " sự " quá trình nhàn rỗi.
user253751
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.