2009-04-02 52 views
9

Chúng tôi có dự án sử dụng gcc và tạo tệp. Dự án cũng chứa một tiểu dự án lớn (SDK) và rất nhiều tiểu dự án tương đối nhỏ sử dụng SDK đó và một số khung công tác được chia sẻ.GCC/Tối ưu hóa thời gian xây dựng

Chúng tôi sử dụng các tiêu đề được biên dịch trước, nhưng điều đó chỉ giúp cho việc biên dịch lại nhanh hơn.

Có bất kỳ kỹ thuật và công cụ đã biết nào để giúp tối ưu hóa thời gian xây dựng không? Hoặc có thể bạn biết một số bài viết/tài nguyên về chủ đề này hoặc các chủ đề liên quan?

Trả lời

14

Bạn có thể giải quyết vấn đề từ hai phía: cấu trúc lại mã để giảm độ phức tạp mà trình biên dịch đang thấy, hoặc tăng tốc độ thực thi trình biên dịch.

Nếu không chạm vào mã, bạn có thể thêm sức mạnh biên dịch vào đó. Sử dụng ccache để tránh biên dịch lại các tệp bạn đã biên dịch và phân phối để phân phối thời gian xây dựng trong số nhiều máy hơn. Sử dụng make -j trong đó N là số lõi + 1 nếu bạn biên dịch cục bộ hoặc một số lớn hơn cho các bản dựng được phân phối. Cờ đó sẽ chạy nhiều hơn một trình biên dịch song song.

Tái cấu trúc mã. Thích khai báo chuyển tiếp để bao gồm (đơn giản). Decouple càng nhiều càng tốt để tránh phụ thuộc (sử dụng thành ngữ PIMPL).

Tạo bản mẫu là tốn kém, chúng được biên dịch lại trong mọi đơn vị biên dịch sử dụng chúng. Nếu bạn có thể cấu trúc lại các khuôn mẫu của bạn để chuyển tiếp khai báo chúng và sau đó khởi tạo chúng chỉ trong một đơn vị biên dịch.

6

Điều tốt nhất tôi có thể nghĩ đến với make là tùy chọn -j. Điều này cho make để chạy như nhiều công việc càng tốt song song:

make -j

Nếu bạn muốn giới hạn số lượng việc làm đồng thời để n bạn có thể sử dụng:

make -jn


Đảm bảo phụ thuộc là chính xác để make không chạy công việc doe không phải.


Một điều cần xem xét là tối ưu mà gcc làm với -O switch. Bạn có thể chỉ định các mức tối ưu hóa khác nhau. Tối ưu hóa càng cao, thời gian biên dịch và liên kết càng dài. Một dự án tôi làm việc với chạy mất 2 phút để liên kết với -O3 và nửa phút với -O1. Bạn nên chắc chắn rằng bạn không tối ưu hóa nhiều hơn mức cần thiết. Bạn có thể xây dựng mà không cần tối ưu hóa cho các bản xây dựng phát triển và tối ưu hóa cho việc xây dựng triển khai.


Biên dịch với thông tin gỡ lỗi (gcc -g) có thể sẽ làm tăng kích thước tệp thực thi và có thể ảnh hưởng đến thời gian xây dựng của bạn. Nếu bạn không cần, hãy thử xóa nó để xem nó có ảnh hưởng đến bạn hay không.


Loại liên kết (tĩnh so với động) sẽ tạo sự khác biệt. Theo như tôi hiểu liên kết tĩnh mất nhiều thời gian hơn (mặc dù tôi có thể sai ở đây). Bạn sẽ thấy nếu điều này ảnh hưởng đến bản dựng của bạn.

+0

Cũng đảm bảo rằng mọi đệ quy được thực hiện để make -j thực sự hoạt động. Ví dụ: không gọi "make -C subdir", hãy sử dụng $ (MAKE), v.v. – richq

+0

Tôi không chắc là tôi hiểu gợi ý đó. –

+2

Nếu makefiles của bạn recurse bằng cách gọi chỉ cần thực hiện, bạn sẽ không nhận được nhiều khả năng mở rộng với -j kể từ khi chỉ cấp cao nhất sẽ sử dụng -j arg, bạn nên sử dụng $ (MAKE) vì nó sẽ gọi submakes với cùng - j và bạn sẽ có cơ hội tốt hơn để có được tất cả công việc đang hoạt động. –

0

Nếu bạn có mạng LAN có máy phát triển, có lẽ bạn nên thử triển khai giải pháp trình biên dịch phân tán, chẳng hạn như distcc.

Điều này có thể không giúp ích nếu tất cả thời gian trong quá trình xây dựng được dành để phân tích phụ thuộc hoặc thực hiện một số tác vụ nối tiếp đơn lẻ. Đối với các crunch thô của biên dịch nhiều tập tin nguồn vào tập tin đối tượng, xây dựng song song rõ ràng là giúp, như đề xuất (trên một máy duy nhất) của Nathan. Song song trên nhiều máy có thể mang nó hơn nữa.

0

http://ccache.samba.org/ tăng tốc thời gian lớn.

Tôi làm việc trên một dự án có kích thước trung bình và đó là điều duy nhất chúng tôi làm để tăng tốc thời gian biên dịch.

+2

Miễn là bạn không làm thủ đoạn ngu ngốc với __DATE __/__ TIME__ hoặc macro liên quan, ccache là tốt đẹp để tăng tốc lặp lại xây dựng sạch. Mặt khác, nếu bạn đang xây dựng thường xuyên, nó có nghĩa là hệ thống xây dựng lại của bạn bị hỏng và bạn nên sửa chữa nó trước ... – ephemient

2

Nếu bạn có nhiều máy tính có sẵn gcc được phân phối tốt bởi distcc.

Bạn cũng có thể sử dụng ccache ngoài ra.

Tất cả điều này hoạt động với rất ít thay đổi về makefiles.

4

Từ mô tả dự án, tôi đoán rằng bạn có một Makefile cho mỗi thư mục và đang sử dụng đệ quy làm cho rất nhiều. Trong trường hợp đó, kỹ thuật từ "Recursive Make Considered Harmful" sẽ giúp ích rất nhiều.

2

Ngoài ra, có thể bạn sẽ muốn giữ các tệp mã nguồn của mình càng nhỏ và càng khả thi càng tốt, nghĩa là thích nhiều tệp đối tượng nhỏ hơn một tệp đối tượng lớn.

Điều này cũng sẽ giúp tránh recompilations không cần thiết, ngoài ra bạn có thể có một thư viện tĩnh với các tập tin đối tượng cho mỗi thư mục mã nguồn hoặc mô-đun, về cơ bản cho phép trình biên dịch sử dụng lại mã càng nhiều biên soạn trước đây càng tốt.

Thứ khác, chưa được đề cập trong bất kỳ câu trả lời nào trước đây, làm cho liên kết biểu tượng là 'riêng tư' càng tốt, nghĩa là thích liên kết tĩnh (hàm, biến) cho mã của bạn nếu nó không phải hiển thị bên ngoài.

Ngoài ra, bạn cũng có thể muốn xem xét sử dụng GNU gold linker, là much more efficient để biên dịch mã C++ cho các mục tiêu ELF. Về cơ bản, tôi khuyên bạn nên cẩn thận cấu hình quá trình xây dựng của bạn và kiểm tra xem thời gian tốn nhiều thời gian nhất, điều đó sẽ cung cấp cho bạn một số gợi ý về cách tối ưu hóa quá trình xây dựng hoặc cấu trúc mã nguồn dự án của bạn.

0

Bạn có thể sử dụng distcc trình biên dịch được phân phối để giảm thời gian xây dựng nếu bạn có quyền truy cập vào một số máy. Dưới đây là một bài báo từ từ developerWorks IBM liên quan đến distcc và làm thế nào bạn có thể sử dụng nó: http://www.ibm.com/developerworks/linux/library/l-distcc.html

Một phương pháp để giảm thời gian xây dựng là sử dụng tiêu đề biên dịch sẵn. Đây là starting point for gcc.

Cũng đừng quên sử dụng -j khi xây dựng với thực hiện nếu máy của bạn có nhiều hơn một cpu/lõi (2x số lõi/cpus là tốt).

2

Bạn có thể xem xét chuyển sang một hệ thống xây dựng khác (mà rõ ràng là sẽ không hoạt động đối với tất cả mọi người), chẳng hạn như SCons. SCons thông minh hơn nhiều so với thực hiện. Nó tự động quét phụ thuộc tiêu đề, vì vậy bạn luôn có bộ phụ thuộc xây dựng lại nhỏ nhất.Bằng cách thêm dòng Decider('MD5-timestamp') vào tệp SConstruct của bạn, trước tiên SCons sẽ xem dấu thời gian của một tệp và nếu nó mới hơn dấu thời gian đã tạo trước đó, nó sẽ sử dụng MD5 của tệp để đảm bảo bạn thực sự đã thay đổi gì đó. Điều này không chỉ hoạt động trên các tệp nguồn mà còn là các tệp đối tượng. Điều này có nghĩa là nếu bạn thay đổi nhận xét, chẳng hạn, bạn không cần phải liên kết lại.

Việc quét tự động các tệp tiêu đề cũng đã đảm bảo rằng tôi không bao giờ phải nhập scons --clean. Nó luôn làm đúng.

0

Sử dụng các tệp nhỏ có thể không phải lúc nào cũng là đề xuất tốt. Một đĩa có kích thước sector 32 hoặc 64K min, với một tệp lấy ít nhất một sector. Vì vậy, 1024 tệp kích thước 3K (mã nhỏ bên trong) sẽ thực sự mất 32 hoặc 64 Meg trên đĩa, thay vì dự kiến ​​3 meg. 32/64 meg cần được đọc bởi ổ đĩa. Nếu các tập tin được phân tán xung quanh trên đĩa bạn tăng thời gian đọc nhiều hơn với thời gian tìm kiếm. Điều này được giúp với Disk Cache rõ ràng, đến một giới hạn. tiêu đề được biên dịch trước cũng có thể giúp ích rất nhiều cho việc giảm bớt điều này. Vì vậy, với sự tôn trọng các hướng dẫn mã hóa, không có điểm nào trong việc thoát ra khỏi chúng chỉ để đặt mỗi strcuct, typedef hoặc lớp tiện ích vào các tệp riêng biệt.

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