Điều gì có thể gây ra để treo khi biên dịch trên nhiều lõi?


17

Hôm qua tôi đã cố gắng biên dịch gói ROOT từ nguồn. Vì tôi đã biên dịch nó trên một cỗ máy quái vật 6 lõi, tôi quyết định tiếp tục và xây dựng bằng nhiều lõi sử dụng make -j 6. Quá trình biên dịch diễn ra suôn sẻ và thực sự nhanh chóng, nhưng tại một số thời điểm, makesử dụng CPU 100% chỉ trên một lõi.

Tôi đã làm một số việc và tìm thấy bài đăng này trên bảng tin ROOT. Kể từ khi tôi tự chế tạo máy tính này, tôi đã lo lắng rằng tôi đã không áp dụng đúng cách tản nhiệt và CPU quá nóng hoặc một cái gì đó. Thật không may, tôi không có tủ lạnh ở đây tại nơi làm việc mà tôi có thể dán nó vào. ;-)

Tôi đã cài đặt lm-sensorsgói và chạy make -j 6lại, lần này theo dõi nhiệt độ CPU. Mặc dù nó đã lên cao (gần 60 C), nhưng nó không bao giờ vượt qua nhiệt độ cao hoặc tới hạn.

Tôi đã thử chạy make -j 4nhưng makeđôi khi bị treo trong lúc biên dịch, lần này ở một điểm khác.

Cuối cùng, tôi biên dịch chỉ chạy makevà nó hoạt động tốt. Câu hỏi của tôi là: Tại sao nó được treo? Do thực tế là nó dừng lại ở hai điểm khác nhau, tôi đoán nó là do một số điều kiện chủng tộc, nhưng tôi nghĩ makenên đủ thông minh để có được mọi thứ theo đúng thứ tự vì nó cung cấp -jtùy chọn.


4
Nó có vẻ như một điều kiện cuộc đua. Một điều bạn có thể làm là gắn vào quy trình tạo đang chạy (quy trình đang quay) bằng cách sử dụng, ví dụ strace -p <pid>và xem liệu bạn có thể tìm hiểu xem nó đang tìm kiếm cái gì không. strace sẽ chỉ hiển thị cho bạn các tòa nhà chọc trời (không phải các cuộc gọi chức năng), nhưng nó vẫn có thể cung cấp cho bạn thông tin có giá trị nếu nó quay trong khi nhìn hoặc tìm một tệp cụ thể.
jlp

Chủ đề bạn tìm thấy qua google dẫn đến kết luận rằng không ai có thể biên dịch nó với -j >1.
Nils

Không liên quan đến việc biên dịch song song, nhưng tôi đã có một makefile treo mà phải mất mãi mãi để gỡ lỗi. Hóa ra nó chỉ đơn giản là trong việc khởi tạo một biến, $(shell ...)cuối cùng đã chạy một lệnh đang chờ đầu vào từ đóstdin . Điều này được gây ra khi một biến trống và không có đối số tệp nào được truyền cho lệnh.
jozxyqk

Câu trả lời:


13

Tôi không có câu trả lời cho vấn đề chính xác này, nhưng tôi có thể cố gắng cung cấp cho bạn một gợi ý về những gì có thể xảy ra: Thiếu phụ thuộc trong Makefiles.

Thí dụ:

target: a.bytecode b.bytecode
    link a.bytecode b.bytecode -o target

a.bytecode: a.source
    compile a.source -o a.bytecode

b.bytecode: b.source
    compile b.source a.bytecode -o a.bytecode

Nếu bạn gọi make targetmọi thứ sẽ biên dịch chính xác. Việc biên dịch a.sourceđược thực hiện (tùy ý, nhưng xác định) trước tiên. Sau đó, việc biên dịch b.sourceđược thực hiện.

Nhưng nếu make -j2 targetcả hai compilelệnh của bạn sẽ được chạy song song. Và bạn sẽ thực sự nhận thấy rằng sự phụ thuộc của Makefile của bạn đã bị phá vỡ. Giả định biên dịch thứ hai a.bytecodeđã được biên dịch, nhưng nó không xuất hiện trong các phụ thuộc. Vì vậy, một lỗi có khả năng xảy ra. Dòng phụ thuộc chính xác cho b.bytecodenên là:

b.bytecode: b.source a.bytecode

Để quay trở lại vấn đề của bạn, nếu bạn không may mắn, có thể lệnh bị treo trong vòng lặp CPU 100%, do thiếu phụ thuộc. Đó có lẽ là những gì đang xảy ra ở đây, sự phụ thuộc bị thiếu không thể được tiết lộ bởi một bản dựng tuần tự, nhưng nó đã được tiết lộ bởi bản dựng song song của bạn.


Hấp dẫn. Bạn có biết nếu có bất kỳ công cụ nào có thể chạy qua makefile và kiểm tra các phụ thuộc này không?
dùng545424

Tôi không biết gì cả. Trong mọi trường hợp, một công cụ như vậy chỉ có thể tìm thấy những sai lầm rõ ràng. Trừ khi nó hiểu cú pháp cho từng lệnh xuất hiện trong Makefile và biết các phụ thuộc (có khả năng tiềm ẩn) là gì.
Stéphane Gimenez

2

Tôi không biết bạn đã có máy bao lâu, nhưng khuyến nghị đầu tiên của tôi là thử kiểm tra bộ nhớ và xác minh rằng bộ nhớ đã hoạt động tốt. Tôi biết nó thường không phải là bộ nhớ là vấn đề, nhưng nếu có, tốt nhất là loại bỏ nó như một nguyên nhân trước khi cố gắng tìm ra các vấn đề có thể khác.


1

Tôi nhận ra đây là một câu hỏi thực sự cũ, nhưng nó vẫn xuất hiện ở đầu kết quả tìm kiếm, vì vậy đây là giải pháp của tôi:

GNU make có một cơ chế máy chủ việc làm để đảm bảo thực hiện và các con đệ quy của nó không tiêu thụ nhiều hơn số lõi đã chỉ định: http://make.mad-scientist.net/ con / joberver-im THỰCation /

Nó dựa trên một đường ống được chia sẻ bởi tất cả các quy trình. Mỗi quy trình muốn phân nhánh thêm trẻ em trước tiên phải tiêu thụ mã thông báo từ đường ống, sau đó từ bỏ chúng khi hoàn tất. Nếu một tiến trình con không trả lại các mã thông báo mà nó đã tiêu thụ, cấp cao nhất sẽ thực hiện trong khi chờ đợi mãi để chúng được trả lại.

https://ormszilla.redhat.com/show_orms.cgi?id=654822

Tôi đã gặp lỗi này khi xây dựng binutils bằng GNU make trên hộp Solaris của tôi, trong đó "sed" không phải là GNU sed. Đấu tranh với PATH để tạo sed == gsed ưu tiên hệ thống sed đã khắc phục vấn đề. Tuy nhiên, tôi không biết tại sao sed lại tiêu thụ token từ đường ống.


0

hệ thống của bạn có thể ổn, nhưng nó có thể là một điều kiện cuộc đua xảy ra makekhi chạy các bản dựng song song.

Nếu có gì đó không ổn với hệ thống của bạn, nó sẽ bị treo / sụp đổ cho các tình huống khác, không chỉ khi thực hiện các bản dựng song song.


0

Đây có thể là một điều kiện cuộc đua, nhưng cũng có thể nếu tất cả việc biên dịch cần thiết được thực hiện song song và chờ đợi người khác, việc liên kết sẽ làm mất thời gian của bạn trên máy. Tôi nghĩ rằng nếu liên kết chờ song song với việc biên dịch cần thiết trước đó, thì bạn sẽ có được tần số cpu cao trên luồng liên kết bất cứ điều gì bạn biên dịch.

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.