2010-02-08 32 views
76

Để thực hiện một bẩn trang (chuyển đổi trên các bit bẩn ở mục bảng trang), tôi chạm vào byte đầu tiên của trang như thế này:Làm thế nào để ngăn chặn gcc tối ưu hóa một số câu lệnh trong C?

pageptr[0] = pageptr[0]; 

Nhưng trong thực tế gcc sẽ bỏ qua các tuyên bố của người chết loại bỏ cửa hàng. Để ngăn gcc tối ưu hóa, tôi viết lại tuyên bố như sau:

volatile int tmp; 
tmp = pageptr[0]; 
pageptr[0] = tmp; 

Dường như mẹo hoạt động, nhưng hơi xấu xí. Tôi muốn biết là có bất kỳ chỉ thị hoặc cú pháp có tác dụng tương tự? Và tôi không muốn sử dụng cờ -O0 vì nó cũng sẽ mang lại hiệu suất tuyệt vời.

+2

bạn đã thử -O0? –

+4

@Mark -O0 sẽ ngừng tối ưu hóa, nhưng cũng làm chậm hiệu suất chương trình. Tôi chỉ muốn tránh tối ưu hóa đoạn mã này: P – ZelluX

Trả lời

65

Tắt tối ưu hóa khắc phục sự cố nhưng không cần thiết. Một giải pháp thay thế an toàn hơn là làm cho trình biên dịch trở nên bất hợp pháp để tối ưu hóa cửa hàng bằng cách sử dụng loại vòng loại loại volatile.

// Assuming pageptr is unsigned char * already... 
unsigned char *pageptr = ...; 
((unsigned char volatile *)pageptr)[0] = pageptr[0]; 

Bộ định loại loại volatile chỉ thị trình biên dịch phải nghiêm ngặt về lưu trữ và tải bộ nhớ. Một mục đích của volatile là để cho trình biên dịch biết rằng truy cập bộ nhớ có tác dụng phụ, và do đó phải được bảo toàn. Trong trường hợp này, cửa hàng có tác dụng phụ gây ra lỗi trang và bạn muốn trình biên dịch bảo toàn lỗi trang.

Bằng cách này, mã xung quanh vẫn có thể được tối ưu hóa và mã của bạn được chuyển sang các trình biên dịch khác không hiểu cú pháp #pragma hoặc __attribute__ của GCC.

+1

Tôi muốn nói điều này là thích hợp hơn để tắt tối ưu hóa. Bạn vẫn có thể hưởng lợi từ các tối ưu hóa khác bằng cách sử dụng phương pháp này. –

+0

Bạn có thực sự cần phải làm một tải từ trang, mặc dù? Chắc chắn chỉ là cửa hàng sẽ làm: '* (volatile int *) pageptr = 0;' – caf

+0

Bạn cần phải sửa đổi chương trình mà sẽ làm cho nó không thể đọc được. – Phong

131

Bạn có thể sử dụng

#pragma GCC push_options 
#pragma GCC optimize ("O0") 

your code 

#pragma GCC pop_options 

để vô hiệu hóa tối ưu hóa từ GCC 4.4.

Xem tài liệu GCC nếu bạn cần thêm chi tiết.

97

Thay vì sử dụng các pragmas mới, bạn cũng có thể sử dụng __attribute__((optimize("O0"))) cho các nhu cầu của mình. Điều này có lợi thế là chỉ áp dụng cho một hàm duy nhất và không phải tất cả các hàm được định nghĩa trong cùng một tệp.

dụ Cách sử dụng:

void __attribute__((optimize("O0"))) foo(unsigned char data) { 
    // unmodifiable compiler code 
} 
+3

Điều gì sẽ xảy ra nếu tôi không sử dụng '-Olevel'option nhưng tôi đã sử dụng các tùy chọn cá nhân mà nó bật tách biệt? * (Trong trường hợp của tôi, tôi không thể xác định tùy chọn tối ưu hóa cá nhân nào đang vi phạm mã) *. – user2284570

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