Clang vs GCC - nơi tạo ra nhị phân tốt hơn? [đóng cửa]


238

Tôi hiện đang sử dụng GCC, nhưng tôi đã phát hiện ra Clang gần đây và tôi đang cân nhắc chuyển đổi. Mặc dù có một yếu tố quyết định - chất lượng (tốc độ, dấu chân bộ nhớ, độ tin cậy) của các nhị phân mà nó tạo ra - nếu gcc -O3có thể tạo ra một nhị phân chạy nhanh hơn 1% hoặc mất ít hơn 1% bộ nhớ, đó là một công cụ giảm giá.

Clang tự hào có tốc độ biên dịch tốt hơn và dung lượng bộ nhớ thời gian biên dịch thấp hơn GCC, nhưng tôi thực sự quan tâm đến điểm chuẩn / so sánh của phần mềm được biên dịch kết quả - bạn có thể chỉ cho tôi một số hoặc mô tả kinh nghiệm của bạn không?


5
Vẫn có vẻ như một câu hỏi và câu trả lời có giá trị, và nhiều người quan tâm.
YasserAsmi

9
@YasserAsmi: Và hai số liệu - dấu chân bộ nhớ và tốc độ thực thi - khác xa tùy ý hoặc tùy thuộc vào "ý kiến". Nhưng có vẻ như căn bệnh Vật lý.SE lây lan ở đây và mọi người bắt đầu bỏ phiếu để đóng mà không đọc chi tiết văn bản câu hỏi ở đây.
SF.

12
câu hỏi yêu cầu điểm chuẩn và so sánh, câu trả lời cho cả hai ... tại sao ý kiến ​​này thay vì so sánh thực tế?
oemb1905

2
Đừng xem tại sao câu hỏi này đã bị đóng. Cho dù đó là ý kiến ​​hay dựa trên thực tế, chúng tôi muốn biết câu trả lời và đánh dấu nó là đóng sẽ mang lại cho nó một xu hướng tiêu cực, nơi không nên có một câu trả lời.
Timothy Makobu

2
@TomZych: Nếu bạn muốn biết những yếu tố này, hãy hỏi những câu hỏi khác nhau. Điều này là rất cụ thể và rõ ràng - yêu cầu tốc độ thực hiện và dấu chân bộ nhớ. Bạn có thể quan tâm đến các yếu tố khác, tốt cho bạn, điều đó không có nghĩa là câu hỏi này không hợp lệ, nó chỉ không đáp ứng sở thích cá nhân của bạn. Giống như bạn là một lập trình viên Java và muốn đóng mọi câu hỏi C # vì nó không nói về Java.
SF.

Câu trả lời:


239

Dưới đây là một số phát hiện cập nhật mặc dù phát hiện hẹp của tôi với GCC 4.7.2 và Clang 3.2 cho C ++.

CẬP NHẬT: So sánh GCC 4.8.1 v clang 3.3 dưới đây.

CẬP NHẬT: So sánh GCC 4.8.2 v clang 3.4 được thêm vào đó.

Tôi duy trì một công cụ OSS được xây dựng cho Linux với cả GCC và Clang và với trình biên dịch của Microsoft cho Windows. Công cụ, coan, là một bộ tiền xử lý và phân tích các tệp nguồn C / C ++ và các bộ mã như vậy: chuyên ngành hồ sơ tính toán của nó về phân tích cú pháp gốc đệ quy và xử lý tệp. Chi nhánh phát triển (mà các kết quả này liên quan) hiện tại bao gồm khoảng 11K LỘC trong khoảng 90 tệp. Hiện tại, nó được mã hóa trong C ++, có tính đa hình và khuôn mẫu phong phú, nhưng vẫn bị sa lầy trong nhiều bản vá bởi quá khứ không quá xa vời của nó trong C. ngữ nghĩa di chuyển không được khai thác rõ ràng. Nó là đơn luồng. Tôi đã không dành nỗ lực nghiêm túc nào để tối ưu hóa nó, trong khi "kiến trúc" vẫn chủ yếu là ToDo.

Tôi đã sử dụng Clang trước 3.2 chỉ như một trình biên dịch thử nghiệm bởi vì, mặc dù tốc độ biên dịch và chẩn đoán vượt trội, nhưng hỗ trợ tiêu chuẩn C ++ 11 của nó đã làm chậm phiên bản GCC đương đại trong các khía cạnh được thực hiện bởi coan. Với 3,2, khoảng cách này đã được đóng lại.

Khai thác kiểm tra Linux của tôi cho quá trình phát triển coan hiện tại xử lý khoảng 70K tệp nguồn trong hỗn hợp các trường hợp kiểm thử trình phân tích cú pháp một tệp, kiểm tra căng thẳng tiêu thụ 1000 tệp và kiểm tra kịch bản tiêu thụ tệp <1K. Cũng như báo cáo kết quả kiểm tra, khai thác tích lũy và hiển thị tổng số tệp được tiêu thụ và thời gian chạy tiêu thụ trong coan (nó chỉ chuyển từng dòng lệnh coan cho lệnh Linux timevà thu thập và cộng các số được báo cáo). Thời gian được tâng bốc bởi thực tế là bất kỳ số lượng thử nghiệm nào mất 0 thời gian có thể đo được đều sẽ cộng với 0, nhưng sự đóng góp của các thử nghiệm đó là không đáng kể. Các thống kê thời gian được hiển thị ở cuối make checknhư thế này:

coan_test_timer: info: coan processed 70844 input_files.
coan_test_timer: info: run time in coan: 16.4 secs.
coan_test_timer: info: Average processing time per input file: 0.000231 secs.

Tôi đã so sánh hiệu suất khai thác thử nghiệm giữa GCC 4.7.2 và Clang 3.2, tất cả mọi thứ đều bằng nhau ngoại trừ các trình biên dịch. Kể từ Clang 3.2, tôi không còn yêu cầu bất kỳ sự khác biệt tiền xử lý nào giữa các vùng mã mà GCC sẽ biên dịch và các lựa chọn thay thế Clang. Tôi đã xây dựng cùng một thư viện C ++ (GCC) trong từng trường hợp và chạy tất cả các phép so sánh liên tiếp trong cùng một phiên cuối.

Mức tối ưu hóa mặc định cho bản phát hành của tôi là -O2. Tôi cũng đã thử nghiệm thành công các bản dựng tại -O3. Tôi đã thử nghiệm mỗi cấu hình 3 lần back-to-back và tính trung bình 3 kết quả, với các kết quả sau. Số trong một ô dữ liệu là số micrô giây trung bình được sử dụng bởi coan thực thi để xử lý mỗi tệp ~ 70K (đọc, phân tích và ghi đầu ra và chẩn đoán).

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 231 | 237 |0.97 |
----------|-----|-----|-----|
Clang-3.2 | 234 | 186 |1.25 |
----------|-----|-----|------
GCC/Clang |0.99 | 1.27|

Bất kỳ ứng dụng cụ thể nào cũng rất có thể có những đặc điểm không phù hợp với điểm mạnh hoặc điểm yếu của nhà soạn nhạc. Điểm chuẩn nghiêm ngặt sử dụng các ứng dụng đa dạng. Với ý nghĩ đó, các tính năng đáng chú ý của các dữ liệu này là:

  1. Tối ưu hóa -3 đã gây bất lợi cho GCC
  2. Tối ưu hóa -O3 rất quan trọng đối với Clang
  3. Ở mức tối ưu hóa -O2, GCC nhanh hơn Clang chỉ bằng một cái râu
  4. Ở mức tối ưu hóa -O3, Clang quan trọng nhanh hơn GCC.

Một so sánh thú vị hơn nữa của hai trình biên dịch đã xuất hiện một cách tình cờ ngay sau những phát hiện đó. Coan tự do sử dụng các con trỏ thông minh và một trong số đó được thực hiện rất nhiều trong việc xử lý tệp. Loại con trỏ thông minh đặc biệt này đã được nhập vào các bản phát hành trước vì mục đích phân biệt trình biên dịch, là một std::unique_ptr<X>trình biên dịch được cấu hình có đủ hỗ trợ cho việc sử dụng nó, và ngược lại std::shared_ptr<X>. Sự thiên vị std::unique_ptrlà ngu ngốc, vì những con trỏ này trên thực tế đã được chuyển đi, nhưng std::unique_ptrtrông giống như tùy chọn fitter để thay thế std::auto_ptrtại một thời điểm khi các biến thể C ++ 11 là tiểu thuyết đối với tôi.

Trong quá trình xây dựng thử nghiệm để đánh giá nhu cầu tiếp tục của Clang 3.2 về sự khác biệt tương tự này, tôi đã vô tình xây dựng std::shared_ptr<X>khi tôi có ý định xây dựng std::unique_ptr<X>và rất ngạc nhiên khi thấy rằng kết quả thực thi, với tối ưu hóa -O2 mặc định, là nhanh nhất đã thấy, đôi khi đạt được 184 msecs. mỗi tệp đầu vào. Với một thay đổi đối với mã nguồn, kết quả tương ứng là những kết quả này;

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 234 | 234 |1.00 |
----------|-----|-----|-----|
Clang-3.2 | 188 | 187 |1.00 |
----------|-----|-----|------
GCC/Clang |1.24 |1.25 |

Những điểm cần lưu ý ở đây là:

  1. Cả trình biên dịch hiện không có lợi ích gì từ tối ưu hóa -O3.
  2. Clang đánh bại GCC cũng quan trọng ở mỗi cấp độ tối ưu hóa.
  3. Hiệu suất của GCC chỉ bị ảnh hưởng nhẹ bởi thay đổi loại con trỏ thông minh.
  4. Hiệu suất -O2 của Clang bị ảnh hưởng quan trọng bởi sự thay đổi loại con trỏ thông minh.

Trước và sau khi thay đổi loại con trỏ thông minh, Clang có thể xây dựng một coan nhanh hơn đáng kể ở mức tối ưu hóa -O3 và nó có thể xây dựng một thực thi nhanh hơn bằng nhau ở -O2 và -O3 khi loại con trỏ đó là loại tốt nhất - std::shared_ptr<X>- cho công việc.

Một câu hỏi rõ ràng mà tôi không đủ thẩm quyền để nhận xét là tại sao Clang có thể tìm thấy tốc độ tăng 25% -O2 trong ứng dụng của tôi khi loại con trỏ thông minh được sử dụng nhiều được thay đổi từ duy nhất sang chia sẻ, trong khi GCC không quan tâm để cùng thay đổi. Tôi cũng không biết mình nên cổ vũ hay la ó khi phát hiện ra rằng tối ưu hóa -O2 của Clang có độ nhạy lớn như vậy đối với sự khôn ngoan trong các lựa chọn con trỏ thông minh của tôi.

CẬP NHẬT: GCC 4.8.1 v clang 3.3

Các kết quả tương ứng bây giờ là:

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.1 | 442 | 443 |1.00 |
----------|-----|-----|-----|
Clang-3.3 | 374 | 370 |1.01 |
----------|-----|-----|------
GCC/Clang |1.18 |1.20 |

Thực tế là tất cả bốn tệp thực thi hiện nay đều mất thời gian trung bình lớn hơn nhiều so với trước đây để xử lý tệp 1 không phản ánh về hiệu suất của trình biên dịch mới nhất. Đó là do thực tế là nhánh phát triển sau này của ứng dụng thử nghiệm đã có rất nhiều phân tích tinh vi trong thời gian đó và trả tiền cho nó theo tốc độ. Chỉ có các tỷ lệ là đáng kể.

Các điểm lưu ý bây giờ không phải là tiểu thuyết bắt mắt:

  • GCC không quan tâm đến tối ưu hóa -O3
  • clang được hưởng lợi rất ít từ tối ưu hóa -O3
  • clang đánh bại GCC bởi một biên độ quan trọng tương tự ở mỗi cấp độ tối ưu hóa.

So sánh các kết quả này với các kết quả cho GCC 4.7.2 và clang 3.2, điều nổi bật là GCC đã lấy lại khoảng một phần tư số clang dẫn đầu ở mỗi cấp độ tối ưu hóa. Nhưng vì ứng dụng thử nghiệm đã được phát triển rất nhiều trong khi đó, người ta không thể tự tin gán cái này cho một sự bắt kịp trong việc tạo mã của GCC. (Lần này, tôi đã lưu ý ảnh chụp nhanh ứng dụng mà từ đó thời gian thu được và có thể sử dụng lại.)

CẬP NHẬT: GCC 4.8.2 v clang 3.4

Tôi đã hoàn thành bản cập nhật cho GCC 4.8.1 v Clang 3.3 nói rằng tôi sẽ sử dụng cùng một snaphot coan để cập nhật thêm. Nhưng thay vào đó, tôi quyết định thử nghiệm trên ảnh chụp nhanh đó (sửa đổi 301) trên ảnh chụp nhanh phát triển mới nhất, tôi đã vượt qua bộ thử nghiệm của nó (sửa đổi 619). Điều này mang lại cho kết quả một chút kinh độ và tôi có một động lực khác:

Bài đăng ban đầu của tôi lưu ý rằng tôi đã không dành nỗ lực để tối ưu hóa coan cho tốc độ. Đây vẫn là trường hợp của rev. 301. Tuy nhiên, sau khi tôi đã xây dựng bộ máy thời gian vào khai thác thử nghiệm coan, mỗi lần tôi chạy bộ thử nghiệm, tác động hiệu suất của những thay đổi mới nhất khiến tôi phải đối mặt. Tôi thấy rằng nó thường lớn một cách đáng ngạc nhiên và xu hướng tiêu cực hơn nhiều so với tôi cảm thấy được khen ngợi bởi sự tăng cường trong chức năng.

Bằng cách sửa đổi 308 thời gian xử lý trung bình cho mỗi tệp đầu vào trong bộ kiểm tra đã tăng hơn gấp đôi kể từ lần đăng đầu tiên ở đây. Vào thời điểm đó, tôi đã thực hiện chính sách 10 năm không bận tâm về hiệu suất. Trong một loạt các sửa đổi, hiệu suất lên tới 619 luôn luôn được xem xét và một số lượng lớn trong số đó đã hoàn toàn viết lại các phần tử tải trọng chính trên các dòng nhanh hơn về cơ bản (mặc dù không sử dụng bất kỳ tính năng biên dịch không chuẩn nào để làm như vậy). Thật thú vị khi thấy phản ứng của mỗi nhà soạn nhạc đối với lần lượt này,

Dưới đây là ma trận thời gian quen thuộc hiện tại cho các bản dựng mới nhất của trình biên dịch rev.301:

coan - rev.301 kết quả

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 428 | 428 |1.00 |
----------|-----|-----|-----|
Clang-3.4 | 390 | 365 |1.07 |
----------|-----|-----|------
GCC/Clang | 1.1 | 1.17|

Câu chuyện ở đây chỉ được thay đổi một chút từ GCC-4.8.1 và Clang-3.3. Hiển thị của GCC là một trifle tốt hơn. Clang's là một trifle tồi tệ hơn. Tiếng ồn cũng có thể giải thích cho điều này. Clang vẫn đi trước -O2-O3lợi nhuận không quan trọng trong hầu hết các ứng dụng nhưng sẽ khá quan trọng đối với một số ít.

Và đây là ma trận cho rev. 619.

coan - rev.619 kết quả

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 210 | 208 |1.01 |
----------|-----|-----|-----|
Clang-3.4 | 252 | 250 |1.01 |
----------|-----|-----|------
GCC/Clang |0.83 | 0.83|

Lấy số liệu 301 và 619 cạnh nhau, một số điểm lên tiếng.

  • Tôi đã nhắm đến việc viết mã nhanh hơn và cả hai trình biên dịch đều minh chứng rõ ràng cho những nỗ lực của tôi. Nhưng:

  • GCC hoàn trả những nỗ lực đó một cách hào phóng hơn Clang. Tại -O2 tối ưu hóa Clang của 619 xây dựng là 46% nhanh hơn so với 301 build của nó: tại -O3cải thiện Clang là 31%. Tốt, nhưng ở mỗi cấp độ tối ưu hóa, bản dựng 619 của GCC nhanh hơn gấp đôi so với 301.

  • GCC nhiều hơn đảo ngược ưu thế trước đây của Clang. Và ở mỗi cấp độ tối ưu hóa, GCC hiện đánh bại Clang 17%.

  • Khả năng của Clang trong bản dựng 301 để có được nhiều đòn bẩy hơn GCC từ -O3tối ưu hóa đã biến mất trong bản dựng 619. Cả trình biên dịch đều tăng một cách có ý nghĩa từ -O3.

Tôi đã rất ngạc nhiên bởi sự đảo ngược của vận may này mà tôi nghi ngờ rằng tôi có thể đã vô tình tạo ra một bản dựng chậm chạp của bản thân 3,4 (vì tôi đã xây dựng nó từ nguồn). Vì vậy, tôi đã chạy lại thử nghiệm 619 với cổ phiếu của bản phân phối Clang 3.3. Kết quả thực tế giống như trong 3,4.

Vì vậy, liên quan đến phản ứng với lượt về: Về các con số ở đây, Clang đã làm tốt hơn nhiều so với GCC ở tốc độ vắt ra khỏi mã C ++ của tôi khi tôi không giúp đỡ. Khi tôi dồn hết tâm trí để giúp đỡ, GCC đã làm một công việc tốt hơn Clang rất nhiều.

Tôi không nâng quan sát đó thành một nguyên tắc, nhưng tôi rút ra bài học rằng "Trình biên dịch nào tạo ra các nhị phân tốt hơn?" là một câu hỏi mà ngay cả khi bạn chỉ định bộ kiểm tra mà câu trả lời sẽ là tương đối, thì đó vẫn không phải là vấn đề rõ ràng về việc chỉ định thời gian cho các nhị phân.

Là nhị phân tốt hơn của bạn là nhị phân nhanh nhất, hay nó là mã bù tốt nhất cho mã được chế tạo rẻ tiền? Hoặc bù đắp tốt nhất cho tốn kém đang crafted rằng ưu tiên bảo trì và tái sử dụng hơn tốc độ? Nó phụ thuộc vào bản chất và trọng lượng tương đối của động cơ của bạn để tạo ra nhị phân và các ràng buộc mà bạn làm như vậy.

Và trong mọi trường hợp, nếu bạn quan tâm sâu sắc đến việc xây dựng các nhị phân "tốt nhất" thì tốt hơn hết bạn nên kiểm tra xem các trình biên dịch liên tiếp cung cấp như thế nào về ý tưởng "tốt nhất" của bạn qua các lần lặp liên tiếp của mã.


9
Tại sao tiếng kêu nhanh hơn? ví dụ, trình biên dịch intel đã sử dụng các đặc tính của chip intel. clang sử dụng để có được một lợi thế là gì? mã có thể được viết lại để gcc có hiệu suất tương tự không?
kirill_igum

27
@krill_igum GCC và clang là các chương trình (rất phức tạp) khác nhau được viết bởi các nhóm lập trình viên khác nhau để thực hiện cùng một công việc: dịch mã nguồn thành mã đối tượng. Gần như không thể tránh khỏi việc một trong số họ sẽ thực hiện công việc đó tốt hơn so với người khác trong bất kỳ bài kiểm tra nào được chọn tại bất kỳ thời điểm nào. Không cần phải có bất kỳ "điều" đặc biệt nào mà người chiến thắng đang "sử dụng" để "có được lợi thế" và vì cả hai chương trình đều là nguồn mở nên họ không có bí mật nào với nhau.
Mike Kinghan

3
Có thể sử dụng kcachegrindđể xác định chính xác các chức năng trong đó các tệp thực thi được tạo khác nhau về hiệu suất.

4
-1: Đây là một cuốn tiểu thuyết (hoặc bài đăng trên blog) nhiều hơn là một câu trả lời.
John Saunders

60
@JohnSaunders: Điều gì đối với một người là một câu trả lời chi tiết, sâu sắc, cho người khác là một cuốn tiểu thuyết không xứng đáng với sự chú ý của họ. Nói cho tôi biết những gì đặt hai người này ngoài.
SF.

48

Phoronix đã thực hiện một số điểm chuẩn về điều này, nhưng đó là về một phiên bản chụp nhanh của Clang / LLVM từ vài tháng trước. Kết quả là mọi thứ ít nhiều là một cú hích; cả GCC và Clang đều không tốt hơn trong mọi trường hợp.

Vì bạn sử dụng Clang mới nhất, nên nó có thể ít liên quan hơn một chút. Sau đó, một lần nữa, GCC 4.6 dự kiến ​​sẽ có một số tối ưu hóa lớn cho Core 2 và i7.

Tôi cho rằng tốc độ biên dịch nhanh hơn của Clang sẽ đẹp hơn đối với các nhà phát triển ban đầu và sau đó khi bạn đẩy mã ra thế giới, Linux distro / BSD / vv. người dùng cuối sẽ sử dụng GCC cho các tệp nhị phân nhanh hơn.


2
Mới hôm nay tôi chạy một vài điểm chuẩn về tốc độ biên dịch Clang và thật đáng thất vọng cho các tệp C. C thuần túy với 270 KLOC clang chỉ nhanh hơn 25%. Khi tôi thấy tinycc nhanh như thế nào trên linux, đó là một kết quả tồi cho trình biên dịch viết mới. Nó trở nên tốt hơn khi sử dụng tối ưu hóa -O2 / -O3 nhưng vì chúng được sử dụng để phát hành nên hiệu suất của trình biên dịch không thành vấn đề trong trường hợp này.
Lothar

7
@mcandre Có lẽ Nietzche-jou đã được biên dịch bằng Clang, trong khi bạn được biên dịch với GCC.
Mateen Ulhaq

18

Việc Clang biên dịch mã nhanh hơn có thể không quan trọng bằng tốc độ của nhị phân kết quả. Tuy nhiên, đây là một loạt các điểm chuẩn .


12
Thật ra nó có. Trong quá trình phát triển, thời gian biên dịch (và tiêu thụ tài nguyên do biên dịch) nhiều hơn một chút tắc nghẽn so với hiệu suất nhị phân. Rốt cuộc, chúng tôi biên dịch trong chế độ Gỡ lỗi ở giai đoạn này. Chỉ đến khi đến giai đoạn thử nghiệm và chuyển bạn mới chuyển sang chế độ Phát hành và cố gắng lấy nhanh nhất có thể một nhị phân.
Matthieu M.

3
@ Matthieu M: Tôi thề rằng câu trả lời đã nói "có thể ..", như thể anh ta đang đưa ra một mối quan tâm tiềm năng. Tôi đoán có lẽ nó đáng được đề cập bởi vì nó, bạn biết đấy, liên quan đến OP.
JM Becker

Đồng ý, mặc dù tất cả các điểm tốt ở đây. Tôi thà ném vào ổ RAID 0 hoặc 3, SSD, hoặc nhiều hơn & RAM nhanh hơn và có hiệu suất .exe tốt nhất - miễn là các biện pháp đó có thể giúp bạn ngang bằng hoặc đóng. Đôi khi nó cũng hữu ích để phát triển với nhiều hơn một trình biên dịch. Nó có thể giúp bạn biết về các tính năng không di động, VÀ bắt lỗi mà không bị phát hiện hoặc dẫn đến lãng phí thời gian cố gắng gỡ lỗi mã, trình biên dịch tốt hơn sẽ cảnh báo / lỗi.

Hôm nay tôi đã thử so sánh trên một số mã số quan trọng hiệu suất chặt chẽ mà tôi đã viết và GCC chạy nhanh hơn nhiều (22S clang-llvm 25S) bằng cả -O2 & -O3. Hãy suy nghĩ bằng cách sử dụng các trình chuyển đổi trình biên dịch (gcc hoặc clang) bao gồm hầu hết các tính năng không chuẩn và cảnh báo tĩnh. Trong dự án lớn của riêng bạn, không biên dịch hàng loạt mã ppl khác, bạn đang làm gì đó sai trong hệ thống xây dựng của mình nếu thời gian biên dịch chi phối thời gian liên kết. Có các công cụ như ccache.samba.org giúp bạn làm sạch thường xuyên. Một vấn đề khác với việc thay đổi trình biên dịch, là tất cả thời gian đầu tư vào kiểm tra / xác nhận bị vứt bỏ.
Rob11311

code.google.com/p/distcc là một dự án khác có thể tăng tốc thời gian biên dịch hàng loạt, nếu toàn bộ thư viện cần biên dịch lại do thay đổi cấu trúc dữ liệu hoặc cho mục đích xác minh / xác thực
Rob11311

11

Có rất ít sự khác biệt tổng thể giữa GCC 4.8 và clang 3.3 về tốc độ của nhị phân kết quả. Trong hầu hết các trường hợp, mã được tạo bởi cả hai trình biên dịch thực hiện tương tự nhau. Cả hai trình biên dịch này đều thống trị cái kia.

Điểm chuẩn cho biết rằng có một khoảng cách hiệu suất đáng kể giữa GCC và tiếng kêu là trùng hợp ngẫu nhiên.

Hiệu suất chương trình bị ảnh hưởng bởi sự lựa chọn của trình biên dịch. Nếu một nhà phát triển hoặc một nhóm các nhà phát triển chỉ sử dụng GCC thì chương trình có thể được mong đợi sẽ chạy nhanh hơn một chút với GCC so với clang và ngược lại.

Từ quan điểm của nhà phát triển, một điểm khác biệt đáng chú ý giữa GCC 4.8+ và clang 3.3 là GCC có -Ogtùy chọn dòng lệnh. Tùy chọn này cho phép tối ưu hóa không can thiệp vào việc gỡ lỗi, vì vậy, ví dụ luôn có thể có được dấu vết ngăn xếp chính xác. Sự vắng mặt của tùy chọn này trong clang làm cho clang khó sử dụng hơn như một trình biên dịch tối ưu hóa cho một số nhà phát triển.


Gần đây, (3.3 và 4.8) Tôi thậm chí không thấy nhiều sự khác biệt giữa thời gian biên dịch. (trong các chương trình "của tôi" với thời gian biên dịch trong khoảng từ 10 giây đến 30 giây).
alfC

9

Cách duy nhất để xác định điều này là thử nó. FWIW Tôi đã thấy một số cải tiến thực sự tốt khi sử dụng LLVM gcc 4.2 của Apple so với gcc 4.2 thông thường (đối với mã x86-64 với khá nhiều SSE), nhưng YMMV cho các cơ sở mã khác nhau. Giả sử bạn đang làm việc với x86 / x86-64 và bạn thực sự quan tâm đến vài phần trăm cuối cùng thì bạn cũng nên thử ICC của Intel, vì điều này thường có thể đánh bại gcc - bạn có thể nhận được giấy phép đánh giá 30 ngày từ intel.com và thử nó


8

Một điểm khác biệt đặc biệt mà tôi đã lưu ý trên gcc 5.2.1 và clang 3.6.2 là nếu bạn có một vòng lặp quan trọng như:

for (;;) {
    if (!visited) {
        ....
    }
    node++;
    if (!*node) break;
  }

Sau đó, gcc sẽ, khi biên dịch với -O3hoặc -O2, suy đoán không kiểm soát vòng lặp tám lần. Clang sẽ không bỏ qua nó. Qua thử nghiệm và lỗi tôi nhận thấy rằng trong trường hợp cụ thể của tôi với dữ liệu chương trình của tôi, số lượng không kiểm soát đúng là năm vì vậy gcc overshot và clang nhấp nháy. Tuy nhiên, việc ghi đè quá mức gây bất lợi cho peformance nên gcc hoạt động kém hơn ở đây.

Tôi không biết liệu sự khác biệt không kiểm soát là một xu hướng chung hay chỉ là một cái gì đó cụ thể cho kịch bản của tôi.

Cách đây không lâu, tôi đã viết một vài người thu gom rác để dạy bản thân nhiều hơn về tối ưu hóa hiệu suất trong C. Và kết quả tôi nhận được là trong tâm trí tôi đủ để hơi ủng hộ tiếng kêu. Đặc biệt là vì bộ sưu tập rác chủ yếu là về đuổi theo con trỏ và sao chép bộ nhớ.

Kết quả là (số tính bằng giây):

+---------------------+-----+-----+
|Type                 |GCC  |Clang|
+---------------------+-----+-----+
|Copying GC           |22.46|22.55|
|Copying GC, optimized|22.01|20.22|
|Mark & Sweep         | 8.72| 8.38|
|Ref Counting/Cycles  |15.14|14.49|
|Ref Counting/Plain   | 9.94| 9.32|
+---------------------+-----+-----+

Đây là tất cả mã C thuần túy và tôi không khẳng định về hiệu suất của trình biên dịch khi biên dịch mã C ++.

Trên Ubuntu 15.10, x86.64 và bộ xử lý AMD Phenom (tm) II X6 1090T.


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.