Tại sao mọi người đề xuất tùy chọn -j3 để thực hiện khi có CPU lõi kép?


18

Trong Gentoo Linux, có thể đặt MAKEOPTSbiến trong đó /etc/portage/make.confđể cho biết có makebao nhiêu công việc nên chạy song song khi xây dựng các gói. Vì tôi có CPU lõi kép, tôi ngây thơ chọn sử dụng -j2tùy chọn: một công việc cho mỗi lõi, vì vậy cả hai đều có việc phải làm. "Vấn đề" là có rất nhiều tài liệu tham khảo cho biết người dùng có CPU lõi kép để đặt -j3tùy chọn thay thế. Một số trong số họ là:

Ví dụ: cẩm nang Gentoo nói:

Một lựa chọn tốt là số lượng CPU (hoặc lõi CPU) trong hệ thống của bạn cộng với một, nhưng hướng dẫn này không phải lúc nào cũng hoàn hảo.

Nhưng lý do căn bản của quy tắc "CPU + 1" là gì? Tại sao việc làm thêm?

Trang man make.conf (5) thậm chí còn cho biết:

Các cài đặt được đề xuất nằm giữa CPU + 1 và 2 * CPU + 1.

Tôi cũng đã đọc phần 5.4 (Thi hành song song) trong maketrang thông tin và makegiải thích trang man cho -jtùy chọn, nhưng dường như không có câu trả lời nào ở đó.



Câu trả lời:


13

Không có một quy tắc đơn giản nào luôn hoạt động. Mọi người có thể đề xuất một con số cụ thể vì họ đã thử nghiệm một phần tổng hợp cụ thể trên một máy cụ thể và đây là cài đặt tốt nhất hoặc vì họ tuân theo một số lý do có thể có hoặc không liên quan đến thực tế.

Nếu bạn may mắn có nhiều RAM, thì yếu tố giới hạn trong quá trình biên dịch dài sẽ là thời gian CPU. Sau đó, một tác vụ cho mỗi CPU, cộng với một tác vụ đang chờ xử lý cho các khối I / O không thường xuyên này, là một cài đặt tốt. Điều đó làm cho nó trở thành -j3CPU lõi kép (hay chính xác hơn là cho máy CPU kép - nếu mỗi lõi được siêu phân luồng, đó sẽ là 4 CPU, vì vậy -j5).

Nếu bạn có rất ít RAM, thì một yếu tố hạn chế có thể là bạn không thể có nhiều công việc đồng thời, nếu không họ sẽ tiếp tục trao đổi lẫn nhau. Ví dụ: nếu bạn không thể thoải mái phù hợp với hai phiên bản trình biên dịch trong bộ nhớ, make -j2có thể đã chậm hơn make. Vì điều này phụ thuộc vào số lượng quá trình biên dịch mà bạn có thể phù hợp với RAM cùng một lúc, không có cách nào để lấy được một con số chung.

Ở giữa, nó có thể có lợi để có nhiều việc làm hơn. Nếu mỗi quá trình biên dịch là nhỏ, nhưng toàn bộ quá trình xây dựng chạm vào rất nhiều dữ liệu, thì I / O của đĩa có thể là yếu tố chặn. Trong trường hợp này, bạn sẽ muốn một số công việc trên mỗi CPU cùng một lúc, để luôn có một công việc sử dụng mỗi CPU trong khi các công việc khác đang chờ I / O. Một lần nữa, điều này phụ thuộc rất nhiều vào công việc xây dựng và RAM có sẵn, ở đây là những gì có sẵn cho bộ đệm dữ liệu (có một cách tối ưu sau khi có quá nhiều công việc làm ô nhiễm bộ đệm quá nhiều).


Tôi không biết rằng nếu các lõi CPU được siêu phân luồng, thì mỗi lõi được tính là hai. Dù sao, có vẻ như CPU của tôi không hỗ trợ Hyper Threading.
Francesco Turco

Tôi chấp nhận câu trả lời này. Dù sao tôi đã chọn gắn bó với -j2hệ thống của tôi. Điều này là do tôi đã thử xuất hiện cả hai gccfirefoxvới các cài đặt từ -j1tối đa -j5(cho tổng số 10 lệnh xuất hiện) và dường như trong khi -j2chắc chắn là nhanh hơn -j1, ba cài đặt khác ngang bằng -j2.
Francesco Turco

7

Tôi đoán đây là một kiểu heuristic - cho phép makekhởi chạy CPUs + 1các quy trình là để đảm bảo rằng:

  1. sẽ không có một khoảng cách giữa một quy trình công nhân vừa hoàn thành và một công nhân chưa chạy - hơi giống như hàng đợi chạy trước khi điền.
  2. sẽ không có quá nhiều quá trình cạnh tranh để mang lại chi phí đáng chú ý với việc điền trước hàng đợi chạy đó.

Nhưng, một lần nữa, đó là cuốn sổ tay heuristic và FreeBSD vẫn khuyên make -j4 dùng cho một CPU.


5

Nói chung, có những lý do để bắt đầu nhiều công việc hơn số lượng lõi. Đối với việc biên dịch C bằng gcc, nếu -pipe không được xác định trong các tùy chọn gcc, thì nó thực hiện các hành động của nó (tiền xử lý, chạy đầu tiên, tối ưu hóa và lắp ráp) theo trình tự bằng cách sử dụng các tệp tạm thời; -pipe thay đổi điều này để sử dụng đường ống giữa các quy trình con. (Thêm -pipe là mặc định, ví dụ như FreeBSD nhưng không truyền thống trên Linux.) Vì vậy, nếu bạn có 2 lõi và cho phép 2 công việc song song, chúng sẽ dành một chút thời gian trong I / O trên đĩa. Đề xuất để thêm 1 công việc dường như có liên quan với chi tiết cụ thể này. Nhưng để có câu trả lời cuối cùng, bạn nên tìm ai và khi thêm đề xuất này và hỏi anh ấy :) hoặc hỏi trong danh sách gửi thư của Gentoo devels.


2

Về cơ bản con số đó là những gì các tác giả gọi là lẽ thường. Tốt nhất, đó là một dự đoán tốt. Theo như tôi biết thì quy trình tạo ra được sinh ra khi bạn gõ makeđã được tính để -j3bạn có thể kết thúc với quy trình chính đang chờ, trong khi hai quy trình khác đang biên dịch.

Tuy nhiên, trở lại khi tôi sử dụng Gentoo, quy tắc của ngón tay cái là <#cpus>*2 + 1.

Tất cả đều xoay quanh những gì con gà của bạn, lá trà hoặc quả bóng ma thuật 8 cho bạn biết về I / O đĩa cần diễn ra và lập lịch trình cho nhân linux hiện tại của bạn. [bắt đầu cốt lõi của bài đăng này] Từ trải nghiệm cá nhân của tôi ( -jkhông phải là cụ thể của Gentoo), mọi thứ giữa #cpus + 1 và #cpus * 2 +1 đều mang lại kết quả tốt [kết thúc cốt lõi của bài đăng này] và trung bình bạn sẽ khó nhận thấy bất kỳ sự khác biệt nào. Bộ xử lý và hạt nhân là khá tốt những ngày này.

NHƯNG tất cả những điều này thay đổi khi: a) bạn thực sự sử dụng nhiều hơn một hộp để biên dịch (du'h) hoặc b) đang phát triển mã của riêng bạn

Một -jthuộc tính cao hơn có nhiều khả năng hiển thị các phụ thuộc chưa biết trước đó.

Và một lưu ý phụ: không đi theo số lượng lõi, mà bằng số lượng luồng đồng thời mà CPU thực hiện. (Siêu văn!)

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.