2014-07-25 17 views
7

Theo this bài viết/video:đúp Compilation của C Mã để Giảm Thực hiện Times

GCC công nhận nhiều tối ưu hóa kiến ​​trúc phụ thuộc cho tăng tốc độ của thực thi C. Thông qua một thực thi thông qua GCC lần thứ hai thường có thể cung cấp hiệu suất đáng kể cải thiện .

Nếu bạn xem video trên liên kết, bạn có thể thấy phương pháp này tăng gấp đôi tốc độ thực thi. Tôi không chắc chắn nếu điều này là chung chung.

Câu hỏi của tôi là: Tại sao điều này xảy ra?

Phần thưởng: Điều gì xảy ra khi chúng tôi biên dịch lại chính xác chương trình đã biên dịch?

+13

Đó là trò lừa bịp. Xem cách mã chứa 'sleep (10)'? Đó là một cuộc gọi hệ thống đặt quá trình ngủ trong mười giây. Tại sao "biên dịch kép" khiến giấc ngủ giảm một nửa thời gian của nó? Lưu ý cách áp phích không liệt kê các tệp sau khi chạy chương trình đầu tiên. –

+0

@JoachimPileborg đó là lý do tại sao tôi yêu cầu ở đây lol :) đây là lần đầu tiên tôi thấy điều đó –

+3

Mười giây chạy chương trình đầu tiên là thời gian dồi dào để chỉnh sửa nguồn và đổi tên thành 'được biên dịch' trong một thiết bị đầu cuối không được ghi lại. Hãy nhớ rằng các hậu tố tên tệp (như '.c') là tùy chọn trong các hệ thống POSIX (như Linux). :) –

Trả lời

46

Đây là trò lừa bịp.

Không gcc cũng như bất kỳ trình biên dịch nào khác có khả năng đọc mã đối tượng, "biên dịch" và tạo mã đối tượng nhanh hơn.

Điều gần nhất là biên dịch phản hồi, khi bạn biên dịch chương trình bằng công cụ (ví dụ gcc --fprofile-generate), hãy chạy chương trình đó, tạo tệp dữ liệu về chạy (ví dụ: foo.gcda) và sau đó biên dịch lại chương trình bằng cùng một mã nguồn và tệp dữ liệu làm đầu vào cho trình biên dịch (ví dụ: gcc --fprofile-use). Điều này có thể dẫn đến tăng tốc khá khiêm tốn, thường là từ 5% đến 10% trong kinh nghiệm của tôi.

Giả sử bạn có một chuỗi dài 50 if … else if cấu trúc (không thể tuân thủ để được cấu trúc lại dưới dạng switch). Điều này thường xảy ra trong các mô phỏng Monte Carlo, ví dụ. Nếu bạn là một lập trình viên có kinh nghiệm hợp lý, có thể bạn sẽ đặt hàng những thứ này để nhánh được lấy thường xuyên nhất xuất hiện trước tiên. Ý tưởng là, trong thời gian chạy, bạn không lãng phí thời gian xem xét 30 chi nhánh ít có khả năng hơn trước khi xem xét nhiều khả năng nhất. Hơn nữa, bạn sẽ cố gắng đặt hàng các chi nhánh này nhiều khả năng ít nhất, do đó, trung bình, số lần kiểm tra chi nhánh nhỏ nhất được thực hiện trước khi tìm thấy đúng. Lưu ý rằng trình biên dịch không có cơ sở để đặt hàng các chi nhánh này bởi vì thông tin mà một người có nhiều khả năng hơn đơn vị khác không nằm trong mã nguồn, vì vậy tốt nhất có thể thực hiện là xuất các nhánh trong thứ tự nguồn.

Với trình biên dịch phản hồi theo hướng cổ điển, trước tiên bạn tạo phiên bản có thể thực thi của tệp thực thi (khi bạn chạy nó) ghi lại số lần mỗi nhánh được lấy (hoặc không) vào tệp dữ liệu. Lần thứ hai bạn biên dịch, trình biên dịch có dữ liệu thực nghiệm từ thời gian chạy (thường không có) có thể được sử dụng để sắp xếp lại các kiểm tra và chèn các gợi ý nhánh để làm cho mã chạy nhanh hơn… ít nhất là với khối lượng công việc tương tự như chương trình thử nghiệm sơ lược.

Tôi chắc chắn rằng trình biên dịch phản hồi theo hướng hiện đại là phức tạp hơn nhiều, nhưng đây là ý tưởng chung.

+4

Hãy nhớ rằng "biên dịch phản hồi hướng dẫn" về cơ bản là những gì một Java "Just In Time Compiler" hiện. –

+0

Không giống nhau, nhưng [một khái niệm liên quan được minh họa ở đây độc đáo] (http://stackoverflow.com/a/11227902/20670). –

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