2015-03-11 36 views
9

xem xét mã C sau:Tại sao trình biên dịch không tối ưu hóa quá trình khởi tạo này?

extern void foo(int* ip); 

void myfunc(void) 
{ 
    int arr[15] = {0}; 
    for (int i=0; i<10; i++) 
    { 
     arr[i] = 42; 
    } 

    foo(arr); 
} 

Tôi đã thử với gcc và kêu vang, với -O3-Os. Trong mọi trường hợp, hội đồng biên soạn viết tất cả 15 zero trước khi ghi đè lên 10 trong số họ với 42.

Tôi cho rằng nó chỉ có thể là không tối ưu hóa đã được viết cho trường hợp này, nhưng nó có vẻ như một trường hợp khá rõ ràng và phổ biến đến tôi. Có điều gì ngăn cản tối ưu hóa không?

Tôi đang trên x86-32 Linux và sử dụng các lệnh này:

gcc -std=c99 -S -O3 hello.c 
clang -std=c99 -S -O3 hello.c 
+6

Đó là luôn luôn có thể đánh bại các trình biên dịch bằng cách viết code ngu ngốc - bạn cần một trình biên dịch vô cùng phức tạp để xử lý tất cả sự thiếu hiệu quả có thể là một lập trình viên vớ vẩn có thể giới thiệu . –

+1

Đây là một ví dụ đơn giản cố ý, nhưng tôi nghĩ rằng nó là khá phổ biến để đầu tiên zero-khởi tạo một struct và sau đó viết vào một số lĩnh vực. –

+0

Bạn có nghĩ rằng trình biên dịch sẽ tạo mã để khởi tạo các phần tử '[10..14]', trên cơ sở bạn sắp đặt các phần tử '[0..9]'? –

Trả lời

9

Nó không phải là một lời giải thích rất khoa học, nhưng chỉ là một trực giác (tuy nhiên, tôi xảy ra cho biết một số của bên trong của GCC).

Để đáng tin cậy làm việc tối ưu hóa mà bạn muốn, trình biên dịch sẽ phải quản lý tiểu mảng hoặc lát. Sau đó, nó trở nên rất phức tạp và dễ bị lỗi. Một trình biên dịch tối ưu hóa rằng nhiều khả năng sẽ tiêu thụ rất nhiều bộ nhớ (đối với các biểu diễn tượng trưng của các mảng con) và rất nhiều thời gian biên dịch. Điều này thường không có giá trị nỗ lực (mà sẽ được chi tiêu tốt hơn bên trong trình biên dịch để tối ưu hóa vòng).

BTW, GCC có khuôn khổ plugin và tiện ích mở rộng MELT (MELT là ngôn ngữ cụ thể của miền để mở rộng GCC và tôi là tác giả chính của MELT). Vì vậy, bạn có thể thử thêm một tối ưu hóa mới vượt qua (thông qua một phần mở rộng MELT hoặc một số C + + plugin) làm công việc. Bạn sẽ sớm nhận ra rằng vượt qua của bạn sẽ là một trong hai đặc biệt cụ thể hoặc sẽ yêu cầu xử lý rất nhiều đại diện nội bộ GCC, và có khả năng thổi lên thời gian biên dịch và bộ nhớ cho rất ít lợi ích.

Lưu ý rằng cả GCC và Clang đều khéo léo bỏ hai vòng (và điều đó có ý nghĩa rất nhiều về hiệu năng).

BTW, Frama-C (một phân tích tĩnh cho các chương trình C được phát triển bởi các đồng nghiệp) phân tích giá trị dường như có thể suy ra đặc tính tốt về bạn arr

Vì vậy, cảm thấy tự do để thêm tối ưu hóa mà để GCC. Nếu bạn không biết (hoặc không có thời gian - nhiều tháng hoặc nhiều năm) làm thế nào để thêm nó, hãy trả tiền cho một công ty hoặc một tổ chức có thể tăng cường GCC cho nhu cầu của bạn. Nó có lẽ là một triệu euro (hoặc đô la Mỹ)/3 năm dự án để có được rằng tối ưu hóa làm việc trên các trường hợp thú vị.

Nếu bạn nghiêm túc về chi tiêu số tiền như vậy, hãy liên hệ với tôi qua email. Trình biên dịch có tối ưu hóa như vậy sẽ cần một số chẩn đoán để vô hiệu hóa chúng (ví dụ: nếu arr là mảng triệu thành viên và bạn đã mã hóa một số sieve of Erasthothenes, có lẽ không đáng để nỗ lực lưu trữ tất cả các công đoàn các lát phụ của các chỉ mục tổng hợp tại thời gian biên dịch).

BTW, bạn có chấp nhận trình biên dịch tối ưu hóa chậm hơn hai mươi lần (chậm hơn tại thời gian biên dịch) để đạt được (có thể là một phần trăm phần trăm thời gian chạy) không hiếm khi thực tế và không quan trọng? Cuối cùng, tôi không tin rằng đây là trường hợp phổ biến để tối ưu hóa. YMMV.

Bạn có thể có lẽ quan tâm theo nguồn để máy biến áp nguồn như PIPS4U

+0

Điểm tốt. Tuy nhiên, phần MELT đã chân thành rất ít để làm với câu hỏi và, imho, nên được bỏ qua. – edmz

+1

Tôi không đồng ý. MELT được thiết kế để viết các tối ưu hóa như vậy nhanh hơn (vì nó cao hơn một chút so với ngôn ngữ C++ được sử dụng bên trong GCC). Nhưng ngay cả với MELT, nó là một công việc lớn. –

+0

Thật tuyệt vời khi nghe. Nhưng OP không hỏi bạn cách thực hiện điều đó; (s) ông hỏi bạn * tại sao * nó đã không được tối ưu hóa. – edmz

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