2009-02-12 23 views
57

Gần đây tôi đã có nguyên nhân làm việc với một số dự án Visual Studio C++ với các cấu hình Gỡ lỗi và Phát hành thông thường, mà còn là 'Phát hành Tất cả' và 'Gỡ lỗi Tất cả' mà tôi chưa từng thấy trước đó.#include tất cả các tệp .cpp thành một đơn vị biên dịch đơn?

Nó chỉ ra tác giả của các dự án có một ALL.cpp đơn mà #bao gồm tất cả các tệp .cpp khác. * Tất cả các cấu hình chỉ xây dựng một tập tin ALL.cpp này. Tất nhiên, nó bị loại trừ khỏi cấu hình thông thường và cấu hình thông thường không xây dựng ALL.cpp

Tôi chỉ tự hỏi đây có phải là thực tiễn phổ biến không? nó mang lại những lợi ích gì? (Phản ứng đầu tiên của tôi là nó có mùi hôi.)

Bạn có thể gặp phải những loại cạm bẫy nào với điều này? Một trong những tôi có thể nghĩ là nếu bạn có không gian tên vô danh trong .cpps của bạn, họ không còn 'riêng' với cpp đó nhưng bây giờ có thể nhìn thấy trong cpps khác không?

Tất cả các dự án đều xây dựng các tệp DLL, vì vậy việc có dữ liệu trong các không gian tên vô danh sẽ không phải là một ý tưởng hay, đúng không? Nhưng chức năng sẽ ổn chứ?

Chúc mừng.

+0

chính thức xây dựng của chúng tôi lúc nào cũng cần xây dựng lại vì vậy tôi tin rằng phương pháp này có thể cải thiện hiệu suất xây dựng rất nhiều. Nhưng kể từ khi xây dựng chính thức chủ yếu được tiêu thụ bởi Devs, nhưng UnityBuild tạo pdbs có thể không hợp lệ cho mã không có unitybuild. (Chúng tôi không muốn phát triển với cấu hình xây dựng hợp nhất, phải không?) –

+0

Lý do hoàn toàn khác để đưa một số tệp triển khai vào một tệp triển khai khác là: các tệp này có thể được tạo tự động. Việc tạo tự động toàn bộ tệp dễ dàng hơn nhiều so với xử lý các thay đổi được chèn vào mã hiện có. –

+1

Chắc chắn bệnh lý; Tôi chỉ có thể đoán lý do tại sao bất cứ ai có thể muốn làm điều đó (nếu bạn, mặt khác, có thể yêu cầu họ trực tiếp, bạn nên). Thông thường trong C++ bạn muốn làm điều ngược lại, không chỉ giữ các tệp triển khai mà còn giữ các phần đầu được tách riêng. (Một cái bẫy chung của các dự án C++ là "#include spaghetti", với mỗi tập tin tiêu đề phụ thuộc vào nhau.) Có lẽ để kiểm tra căng thẳng trình biên dịch? – Morendil

Trả lời

47

Nó được một số (và google-có thể) gọi là "Xây dựng Unity". Nó liên kết nhanh chóng và nhanh chóng biên dịch một cách hợp lý. Thật tuyệt vời cho các bản dựng mà bạn không cần phải lặp lại, như bản phát hành bản phát hành từ máy chủ trung tâm, nhưng không nhất thiết phải xây dựng gia tăng.

Và đó là PITA để duy trì.

EDIT: đây là liên kết google đầu tiên cho biết thêm: http://buffered.io/posts/the-magic-of-unity-builds/

Điều mà làm cho nó nhanh là trình biên dịch chỉ cần đọc trong tất cả mọi thứ một lần, biên dịch ra ngoài, sau đó liên kết, chứ không phải làm điều đó cho mỗi .cpp tệp.

Bruce Dawson có nhiều hơn viết lên về vấn đề này trên blog của mình: http://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/

+19

Nó không chỉ vì I/O. Mỗi tệp .cpp đơn thường bao gồm nhiều tệp tiêu đề. Nếu bạn biên dịch chúng một cách riêng biệt, sau đó bạn biên dịch mã trong các tệp tiêu đề nhiều lần - một lần cho mỗi tệp .o. Nếu bạn sử dụng "Unity Build" thì các tệp tiêu đề này và mọi thứ khác chỉ được biên dịch một lần. – Frank

+5

Er ... nằm trong I/O. Nhưng có, đó là chính xác hơn. – MSN

+8

Biên dịch * không * thường là I/O bị ràng buộc, trừ khi bạn không có đủ bộ nhớ. Xem câu trả lời của tôi xuống dưới đây.Bộ nhớ cache của ổ đĩa hoạt động. Bài đăng được liên kết dành nhiều thời gian cho việc phân tích để giải thích cách hoạt động của I/O đĩa xấu, nhưng nó không liên quan vì bộ đệm đĩa. Ngoài ra, * biên dịch * mã trong các tệp tiêu đề nhiều lần hoàn toàn khác với I/O. Việc biên dịch dư thừa là vấn đề, I/O thừa không bao giờ thực sự xảy ra. Một số hiểm họa của các bản xây dựng đoàn kết được đề cập ở đây: http://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/ –

6

Tôi tự hỏi nếu đó ALL.cpp đang nỗ lực để đưa toàn bộ dự án trong phạm vi một đơn vị biên dịch duy nhất, để cải thiện khả năng cho trình biên dịch để tối ưu hóa chương trình cho kích thước?

Thông thường, một số tối ưu hóa chỉ được thực hiện trong các đơn vị biên dịch riêng biệt, chẳng hạn như loại bỏ mã trùng lặp và nội tuyến. Điều đó nói rằng, tôi có vẻ nhớ rằng các trình biên dịch gần đây (Microsoft, Intel, nhưng tôi không nghĩ điều này bao gồm GCC) có thể thực hiện tối ưu hóa này trên nhiều đơn vị biên dịch, vì vậy tôi nghi ngờ rằng 'lừa' này là không cần thiết.

Điều đó nói rằng, sẽ rất tò mò muốn biết liệu có sự khác biệt nào không.

+2

Visual C++ có thể làm tối ưu toàn bộ chương trình với/LTCG switch (tạo mã thời gian liên kết) –

+1

những ngày này, GCC và clang cũng hỗ trợ LTO – justin

+0

Sau đó, nó chắc chắn không cần thiết. – Arafangion

40

Unity xây dựng tốc độ xây dựng được cải thiện vì ba lý do chính. Lý do đầu tiên là tất cả các tệp tiêu đề được chia sẻ chỉ cần được phân tích cú pháp một lần. Nhiều dự án C++ có rất nhiều tệp tiêu đề được bao gồm bởi hầu hết hoặc tất cả các tệp CPP và phân tích dự phòng trong số này là chi phí biên dịch chính, đặc biệt nếu bạn có nhiều tệp nguồn ngắn. Các tệp tiêu đề biên dịch sẵn có thể giúp với chi phí này, nhưng thường có rất nhiều tệp tiêu đề không được biên dịch trước.

Lý do chính tiếp theo là sự hợp nhất xây dựng cải thiện tốc độ xây dựng là do trình biên dịch được gọi ít lần hơn. Có một số chi phí khởi động với việc gọi trình biên dịch.

Cuối cùng, việc giảm phân tích cú pháp tiêu đề dư thừa có nghĩa là giảm mã dự phòng cho các chức năng nội tuyến, do đó tổng kích thước của tệp đối tượng nhỏ hơn, giúp liên kết nhanh hơn.

Xây dựng hợp nhất cũng có thể cung cấp mã nguồn tốt hơn.

Xây dựng hợp nhất là NOT nhanh hơn vì giảm I/O đĩa. Tôi đã lược tả nhiều bản dựng với xperf và tôi biết mình đang nói về cái gì. Nếu bạn có đủ bộ nhớ thì bộ nhớ cache của ổ đĩa hệ điều hành sẽ tránh được I/O dư thừa - các lần đọc tiếp theo của một tiêu đề sẽ đến từ bộ đệm đĩa của hệ điều hành. Nếu bạn không có đủ bộ nhớ thì các bản dựng hợp nhất thậm chí có thể làm cho thời gian xây dựng tồi tệ hơn bằng cách làm cho bộ nhớ của trình biên dịch vượt quá bộ nhớ sẵn có và được phân trang.

Đĩa I/O đắt tiền, đó là lý do tại sao tất cả các hệ điều hành tích cực lưu trữ dữ liệu để tránh dư thừa đĩa I/O.

+1

Câu trả lời đúng nhất ở đây. Đối với các dự án lớn không có thay thế cho tốc độ xây dựng. BTW đề nghị msbuild/LTCG tăng thời gian liên kết từ 4 phút đến qua đêm! (Clang tốt hơn). – ChocoBilly

+0

Lưu ý rằng VS 2015 sửa lỗi được liệt kê bên dưới, làm cho các liên kết LTCG chạy nhanh hơn đáng kể - nhanh hơn ba lần so với một số thử nghiệm quy mô lớn gần đây. https://connect.microsoft.com/VisualStudio/feedback/details/1064219/ltcg-linking-of-chromes-pdf-dll-spends-60-of-time-in-c2-dll-ssrfree –

+0

Đúng. Biên dịch C++ là chậm vì mỗi đơn vị biên dịch phải được biên dịch riêng biệt [Tại sao quá trình biên dịch C++ mất quá lâu?] (Http://stackoverflow.com/q/318398/995714) –

1

Tôi đồng ý với Bruce; từ kinh nghiệm của tôi, tôi đã thử triển khai Unity Build cho một trong các dự án .dll của tôi có một tấn tiêu đề bao gồm và rất nhiều .cpps; để giảm thời gian tổng hợp Compilation trên VS2010 (đã cạn kiệt tùy chọn Build Incremental) nhưng thay vì cắt giảm thời gian Compilation, tôi hết bộ nhớ và Build không thể hoàn thành Compilation.

Tuy nhiên để thêm; Tôi đã tìm thấy cho phép tùy chọn Compilation Multi-Processor trong Visual Studio khá giúp trong việc cắt giảm thời gian Compilation; Tôi không chắc chắn nếu một tùy chọn như vậy có sẵn trên các trình biên dịch nền tảng khác.

+2

Nếu bạn đồng ý và không thêm bất kỳ thứ gì, nó không Có vẻ như đây không phải là câu trả lời. Điều này nghe có vẻ giống như một câu chuyện và bình luận. – RacerNerd

+1

Thực ra; Tôi dự định để thêm một bình luận về kinh nghiệm của riêng tôi với vấn đề này (trên một sức mạnh công nghiệp và kích thước mã cơ bản); đối với một người cố gắng như vậy bởi vì ý tưởng về Unity Builds đưa ra ấn tượng rằng nó gần như sẽ dẫn đến việc biên dịch ít hơn; đó không phải là trường hợp cho các dự án lớn. Lý do tại sao chúng tôi sẽ cố gắng này ở nơi đầu tiên; nhưng tôi không ai loại trừ các trường hợp ngoại lệ và những cân nhắc thiết kế nhất định. – spforay

Các vấn đề liên quan