Làm thế nào người ta có thể hạn chế số lượng lõi CPU mà mỗi người dùng có thể sử dụng?


17

Chúng tôi có một máy tính có CPU có 32 lõi và nó sẽ được sử dụng để chạy các chương trình bởi một vài người dùng khác nhau. Có cách nào để hạn chế số lượng lõi mà mỗi người dùng có thể sử dụng bất cứ lúc nào để một người dùng sẽ không độc quyền tất cả sức mạnh của CPU không?


5
Không phải là một câu trả lời, chỉ là một ý tưởng. Bạn có thể muốn xem xét việc thiết lập một số máy ảo. Mỗi cái chỉ có thể có một lượng CPU-s giới hạn. Mỗi người dùng sẽ chỉ ở một trong các máy ảo và người dùng trên VM đó sẽ bị hạn chế sử dụng CPU. Có thể một số phần mềm ảo hóa có các công cụ hỗ trợ này.
ghellquist

1
@ghellquist bạn nên đưa ra câu trả lời
slebetman

@ghellquist: Bạn có thể muốn một cái gì đó nhẹ nhất có thể, như các thùng chứa Linux, nếu bạn chỉ muốn những người dùng khác nhau chỉ nhìn thấy một số CPU. (ví dụ như vậy khi họ khởi động OpenMP hoặc chương trình khác khởi động nhiều luồng như nó thấy lõi, nó sẽ bắt đầu một số thích hợp cho số lượng lõi bạn cho phép mỗi người dùng thực sự sử dụng). Ảo hóa hoàn toàn, như KVM, có chi phí hiệu năng ngay cả với hỗ trợ phần cứng như VT-X hoặc AMD-V, từ các cấp bảng bổ sung ngay cả khi tránh thoát VM, trong mã có bất kỳ lỗi TLB nào khi chạm vào nhiều bộ nhớ.
Peter Cordes

Tôi xin lỗi, nhưng thậm chí có cần một thứ này không? Là một hệ thống nhiều người dùng, Linux theo mặc định đã thực hiện đa nhiệm được ưu tiên, do đó, tình huống mà một người dùng (không độc hại) chỉ tự mình xử lý toàn bộ hệ thống.
Khối

Câu trả lời:


16

Trong khi điều này là có thể , nó phức tạp và gần như chắc chắn là một ý tưởng tồi. Nếu chỉ có một người dùng đang sử dụng máy tại thời điểm này, việc giới hạn họ ở lõi N là một sự lãng phí tài nguyên. Một cách tiếp cận tốt hơn sẽ là chạy mọi thứ với nice:

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).

Đây là một công cụ tuyệt vời đặt ưu tiên của một quy trình. Vì vậy, nếu chỉ có một người dùng đang chạy một cái gì đó, họ sẽ nhận được nhiều thời gian CPU như họ cần, nhưng nếu ai đó khởi động công việc của riêng họ (cũng được bảo vệ), họ sẽ tốt và chia sẻ với nhau. Theo cách đó, nếu tất cả người dùng của bạn khởi chạy các lệnh với nice 10 command, sẽ không có ai chiếm dụng tài nguyên (và không ai sẽ đưa máy chủ đến đầu gối của nó).

Lưu ý rằng giá trị cao đẹp có nghĩa là mức độ ưu tiên thấp. Đây là thước đo mức độ tốt đẹp của chúng ta và chúng ta càng đẹp, chúng ta càng chia sẻ nhiều hơn.

Cũng lưu ý rằng điều này sẽ không giúp quản lý cấp phát bộ nhớ, nó chỉ ảnh hưởng đến lập lịch CPU. Vì vậy, nếu nhiều người dùng khởi chạy nhiều tiến trình chiếm nhiều bộ nhớ, bạn vẫn sẽ gặp vấn đề. Nếu đó là một vấn đề, bạn nên xem xét các hệ thống xếp hàng thích hợp như mô-men xoắn .


Cảm ơn câu trả lời của bạn. Có một số "trình quản lý khối lượng công việc" như SLURM nhưng chúng dành cho các máy tính có nhiều nút. Tôi đoán nó có ý nghĩa rằng mọi người đã không phát triển các ứng dụng tương tự cho các máy tính nút đơn vì không có nhiều nhu cầu.
Reza

@Reza hãy thử nice, từ những gì bạn mô tả, đó chính xác là những gì bạn cần.
terdon

3
@Reza: Đó là vì HĐH đã làm điều đó. Nó tự động chia sẻ thời gian các CPU có sẵn cho các luồng / tiến trình khi cần thiết.
BlueRaja - Daniel Pflughoeft

13

TL; DR : Từ nghiên cứu ngắn gọn, có thể hạn chế các lệnh đối với số lượng lõi cụ thể, tuy nhiên trong mọi trường hợp bạn phải sử dụng một lệnh thực sự hạn chế.

nhóm

Linux cgroupsthường được sử dụng chính xác cho mục đích hạn chế tài nguyên có sẵn cho các quy trình. Từ một nghiên cứu ngắn gọn, bạn có thể tìm thấy một ví dụ trong Arch Wiki với cấu hình Matlab (một phần mềm khoa học) được đặt trong /etc/cgconfig.conf:

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}

Để cấu hình như vậy có hiệu lực, bạn phải chạy quy trình thông qua cgexeclệnh, ví dụ từ cùng một trang wiki:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

nhiệm vụ

Một câu hỏi liên quan về Hỏi Ubuntu và Làm cách nào để giới hạn một quy trình trong một lõi CPU trong Linux? [trùng lặp] trên trang web Unix & Linux cho thấy một ví dụ về việc sử dụng tasksetđể giới hạn CPU cho quy trình. Trong câu hỏi đầu tiên, nó đạt được thông qua phân tích tất cả các quy trình cho một người dùng cụ thể

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001

Trong câu hỏi khác, một quá trình được bắt đầu thông qua tasksetchính nó:

$ taskset -c 0 mycommand --option  # start a command with the given affinity

Phần kết luận

Mặc dù chắc chắn có thể hạn chế các quy trình, nhưng có vẻ như không đơn giản để đạt được điều đó cho người dùng cụ thể. Ví dụ trong bài viết Hỏi Ubuntu được liên kết sẽ yêu cầu quét nhất quán các quy trình thuộc về mỗi người dùng và sử dụng tasksettrên mỗi người dùng mới. Một cách tiếp cận hợp lý hơn sẽ là chạy có chọn lọc các ứng dụng chuyên sâu về CPU, thông qua cgexechoặc taskset; Sẽ không có ý nghĩa gì khi hạn chế tất cả các quy trình với số lượng CPUS cụ thể, đặc biệt đối với những quy trình thực sự sử dụng song song và đồng thời để chạy các tác vụ của chúng nhanh hơn - giới hạn chúng với số lượng CPU cụ thể có thể có tác dụng làm chậm quá trình xử lý. Ngoài ra, như câu trả lời của terdon đã đề cập đến việc lãng phí tài nguyên

Chạy các ứng dụng được chọn thông qua tasksethoặc cgexecyêu cầu giao tiếp với người dùng của bạn để cho họ biết những ứng dụng nào họ có thể chạy hoặc tạo tập lệnh bao bọc sẽ khởi chạy các ứng dụng được chọn thông qua taskselhoặc cgexec.

Ngoài ra, hãy xem xét cài đặt số lượng quy trình mà người dùng hoặc nhóm có thể sinh ra thay vì đặt giới hạn số lượng CPU. Điều này có thể đạt được thông qua /etc/security/limits.conftập tin .

Xem thêm


1
tốt, có cgrulesengdcgrules.conf để tự động di chuyển các quy trình sang nhóm thích hợp dựa trên người dùng / nhóm thay vì dựa vào người dùng chạy quy trình của họ bằng cgexec. Nhưng có vẻ như, việc thiết lập này trong ubfox có phần không tầm thường.
Hans-Jakob

@ Hans-Jakob Trông có vẻ hơi phức tạp, cộng với yêu cầu thêm cờ kernel trong GRUB. Có lẽ đối với cấp độ doanh nghiệp của máy, nơi bạn có nhiều người dùng và không muốn họ làm sập hệ thống, điều đó có thể đáng giá, nhưng đối với máy tính để bàn - quá nhiều công việc. Cảm ơn bạn đã liên kết đó.
Sergiy Kolodyazhnyy

2
sched_setaffinity(2)nói mặt nạ ái lực được bảo tồn qua execve(2), rằng một đứa trẻ thừa hưởng nó trên fork(2). Vì vậy, nếu bạn đặt tác vụ cho trình bao cho người dùng (hoặc trình bao đồ họa của họ cho phiên X), mọi thứ họ bắt đầu từ trình bao đó, theo mặc định, sẽ sử dụng cùng một mặt nạ ái lực.
Peter Cordes

1
Một nhược điểm có thể xảy ra là các chương trình kiểm tra xem máy có bao nhiêu CPU khi quyết định bắt đầu có bao nhiêu luồng; họ sẽ có quá nhiều luồng cho số lượng lõi mà họ thực sự sẽ được lên lịch. Bạn đã tìm ra nếu các nhóm có thể làm bất cứ điều gì về điều đó?
Peter Cordes

@PeterCordes Ý tưởng vỏ sinh sản nghe có vẻ thú vị. Tôi sẽ cần phải xem xét điều đó. Cảm ơn ! Đối với bình luận thứ hai, không, tôi đã không nghiên cứu đủ các nhóm vào thời điểm này.
Sergiy Kolodyazhnyy
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.