Câu hỏi nhanh: cờ trình biên dịch để cho phép g ++ sinh ra nhiều phiên bản của chính nó để biên dịch các dự án lớn nhanh hơn (ví dụ 4 tệp nguồn tại một thời điểm cho CPU đa lõi)?
make -j
hầu như luôn mang lại kết quả tốt.
Câu hỏi nhanh: cờ trình biên dịch để cho phép g ++ sinh ra nhiều phiên bản của chính nó để biên dịch các dự án lớn nhanh hơn (ví dụ 4 tệp nguồn tại một thời điểm cho CPU đa lõi)?
make -j
hầu như luôn mang lại kết quả tốt.
Câu trả lời:
Bạn có thể làm điều này với make - với gnu làm cho nó là cờ -j (điều này cũng sẽ giúp ích cho máy không xử lý).
Ví dụ: nếu bạn muốn 4 công việc song song thực hiện:
make -j 4
Bạn cũng có thể chạy gcc trong một đường ống với
gcc -pipe
Điều này sẽ dẫn các giai đoạn biên dịch, cũng sẽ giúp giữ cho các lõi bận rộn.
Nếu bạn cũng có sẵn máy móc, bạn có thể kiểm tra distcc , trang này cũng sẽ biên dịch cho các máy đó.
-j
lập luận
Không có cờ như vậy và có một hoạt động chống lại triết lý Unix là mỗi công cụ chỉ thực hiện một chức năng và thực hiện tốt chức năng đó. Sinh sản các quá trình biên dịch là khái niệm công việc của hệ thống xây dựng. Những gì bạn có thể đang tìm kiếm là cờ -j (công việc) để GNU thực hiện, một la
làm -j4
Hoặc bạn có thể sử dụng pmake hoặc các hệ thống tạo song song tương tự.
Mọi người đã đề cập make
nhưng bjam
cũng hỗ trợ một khái niệm tương tự. Sử dụng bjam -jx
hướng dẫn bjam để xây dựng lên x
các lệnh đồng thời.
Chúng tôi sử dụng cùng một tập lệnh xây dựng trên Windows và Linux và sử dụng tùy chọn này giảm một nửa thời gian xây dựng của chúng tôi trên cả hai nền tảng. Đẹp.
make
sẽ làm điều này cho bạn. Điều tra -j
và -l
chuyển đổi trong trang người đàn ông. Tôi không nghĩ g++
là song song.
-l
tùy chọn (không bắt đầu một công việc mới trừ khi tất cả các công việc trước đó đã chấm dứt). Mặt khác, có vẻ như công việc của trình liên kết bắt đầu với không phải tất cả các tệp đối tượng được xây dựng (vì một số phần tổng hợp vẫn đang tiếp diễn), do đó công việc của trình liên kết không thành công.
Nếu sử dụng make, vấn đề với -j
. Từ man make
:
-j [jobs], --jobs[=jobs] Specifies the number of jobs (commands) to run simultaneously. If there is more than one -j option, the last one is effective. If the -j option is given without an argument, make will not limit the number of jobs that can run simultaneously.
Và đáng chú ý nhất, nếu bạn muốn tập lệnh hoặc xác định số lượng lõi bạn có sẵn (tùy thuộc vào môi trường của bạn và nếu bạn chạy trong nhiều môi trường, điều này có thể thay đổi rất nhiều), bạn có thể sử dụng chức năng Python phổ biến cpu_count()
:
https://docs.python.org/3/l Library / multiprocessing.html # multiprocessing.cpu_count
Như thế này:
make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')
Nếu bạn đang hỏi tại sao 1.5
tôi sẽ trích dẫn tiếng ồn của người dùng trong một bình luận ở trên:
Số 1,5 là do vấn đề ràng buộc I / O được ghi nhận. Đó là một quy tắc của ngón tay cái. Khoảng 1/3 công việc sẽ chờ I / O, vì vậy các công việc còn lại sẽ sử dụng các lõi có sẵn. Một số lớn hơn lõi là tốt hơn và bạn thậm chí có thể lên cao gấp 2 lần.
make -j`nproc`
với nproc
GNU Coreutils.
make -j $(( $(nproc) + 1 ))
(đảm bảo bạn đặt khoảng trắng nơi tôi có chúng).
nproc
không khả dụng, ví dụ như trong manylinux1
các thùng chứa, nó tiết kiệm thêm thời gian bằng cách tránh chạy yum update
/ yum install
.
distcc cũng có thể được sử dụng để phân phối các biên dịch không chỉ trên máy hiện tại mà còn trên các máy khác trong một trang trại đã cài đặt distcc.
Tôi không chắc chắn về g ++, nhưng nếu bạn đang sử dụng GNU Make thì "make -j N" (trong đó N là số lượng chủ đề có thể tạo) sẽ cho phép thực hiện nhiều công việc g ++ nhiều lần (rất lâu như các tập tin không phụ thuộc vào nhau).
-j N
nói rằng làm cho bao nhiêu quá trình cùng một lúc nên được sinh ra, không phải là chủ đề. Đó là lý do tại sao nó không hoạt động như MS cl -MT
(thực sự đa luồng).
GNU song song
Tôi đã thực hiện một chuẩn tổng hợp tổng hợp và không thể bận tâm để viết Makefile, vì vậy tôi đã sử dụng:
sudo apt-get install parallel
ls | grep -E '\.c$' | parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"
Giải trình:
{.}
lấy đối số đầu vào và loại bỏ phần mở rộng của nó-t
in ra các lệnh đang được chạy để cho chúng ta một ý tưởng về sự tiến bộ--will-cite
xóa yêu cầu trích dẫn phần mềm nếu bạn công bố kết quả bằng cách sử dụng nó ...parallel
tiện lợi đến mức tôi thậm chí có thể tự kiểm tra dấu thời gian:
ls | grep -E '\.c$' | parallel -t --will-cite "\
if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
gcc -c -o '{.}.o' '{}'
fi
"
xargs -P
cũng có thể chạy các công việc song song, nhưng sẽ thuận tiện hơn một chút khi thực hiện thao tác mở rộng hoặc chạy nhiều lệnh với nó: Gọi nhiều lệnh thông qua xargs
Liên kết song song được hỏi tại: gcc có thể sử dụng nhiều lõi khi liên kết không?
TODO: Tôi nghĩ rằng tôi đã đọc ở đâu đó rằng quá trình biên dịch có thể được giảm xuống thành phép nhân ma trận, vì vậy có lẽ cũng có thể tăng tốc độ biên dịch tệp đơn cho các tệp lớn. Nhưng tôi không thể tìm thấy một tài liệu tham khảo bây giờ.
Đã thử nghiệm trong Ubuntu 18.10.