2015-07-13 37 views
9

Điều này liên quan đến Determine cause of segfault when using -O3? Trong câu hỏi, tôi đang bắt một segfault trong một chức năng cụ thể khi biên soạn với -O3 bằng cách sử dụng một phiên bản cụ thể của GCC. Tại -O3, hướng dẫn vectơ được sử dụng (tại -O2, chúng không được sử dụng).Làm cách nào để thay đổi mức tối ưu hóa của một chức năng?

Tôi muốn bọc một hàm duy nhất ở mức tối ưu hóa thấp hơn. Theo số Switching off optimization for a specific function in GCC 4.2.2, tôi có thể làm được. Tuy nhiên, theo các liên kết khác nhau trong câu hỏi và câu trả lời, tôi không tìm thấy câu trả lời cho "cách chính xác, để thực hiện".

Làm cách nào để đánh dấu một hàm duy nhất để sử dụng cấp tối ưu hóa khác?


Có liên quan, tôi không muốn di chuyển hàm này sang tệp riêng biệt, sau đó cung cấp công thức makefile khác cho nó. Làm như vậy sẽ mở ra một loại sâu khác, như chỉ áp dụng cho GCC 4.9 trên một số nền tảng.

+3

Chỉ cần sao lưu mà bạn * thực sự * không muốn thực hiện tùy chọn tệp riêng biệt, như thể bạn biên dịch các đơn vị khác nhau với các tùy chọn khác nhau mà bạn đang sử dụng thanh gurguler. –

+0

Nghe như một [XY-problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) với tôi. Nếu mã của bạn không hoạt động với tối ưu hóa, nó rất có khả năng biểu diễn _undefined behaviour_. Nếu điều đó không hiển thị mà không tối ưu hóa thực sự là một dấu hiệu xấu. Thay vì cố gắng để fiddle với tối ưu hóa, bạn dứt khoát nên tìm kiếm nguyên nhân. Trừ khi bạn có thể chứng minh nó là do một lỗi trong trình biên dịch, tất nhiên. Trong trường hợp này, câu hỏi đặt ra cách bạn đảm bảo lỗi này sẽ không hiển thị ở nơi khác. Ở đây, sử dụng một trình biên dịch được vá hoặc mới hơn là cách chính xác. – Olaf

+0

@Olaf - sự cố hiển thị ở '-O3', nhưng không xuất hiện ở' -O2'. Tại '-O3', GCC sử dụng lệnh SSE. Điều tốt nhất tôi có thể nói, 'vmovdqa' yêu cầu các từ được liên kết 128 bit, nhưng mã không đảm bảo nó. Mã này đảm bảo mảng được căn chỉnh 64 bit khi đường dẫn mã cụ thể này được sử dụng. Mã này cũng được làm sạch với Clang và chất khử trùng hành vi không xác định của nó.Tôi nghĩ rằng tôi đang làm việc xung quanh một lỗi trình biên dịch. – jww

Trả lời

6

Nó được mô tả trong https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes

Bạn có thể thay đổi mức độ bằng cách tuyên bố các chức năng như thế này:

void some_func() __attribute__ ((optimize(1))) { 
    .... 
} 

Buộc mức tối ưu hóa 1 cho nó.

+0

có giải pháp di động không? điều này có khả năng di động không? –

+0

Không, đó là GCC cụ thể. Clang có một [optnone] nặng hơn (http://clang.llvm.org/docs/AttributeReference.html#optnone-clang-optnone) sẽ giết tất cả tối ưu hóa. Nhưng cả hai chỉ là tiện ích mở rộng tùy chỉnh. Không có tiêu chuẩn cho tối ưu hóa mức chức năng. – viraptor

+0

Cảm ơn viraptor. Tôi đã hy vọng cho một giải pháp di động vì đây là một thư viện nền tảng chéo. Cùng một tập hợp các nguồn được sử dụng trên Android, BSD, iOS, Linux, OS X, Solaris và Windows. – jww

1

Dưới đây là làm thế nào để làm điều đó với pragmas:

#pragma GCC push_options 
#pragma GCC optimize ("-O2") 
void xorbuf(byte *buf, const byte *mask, size_t count) 
{ 
    ... 
} 
#pragma GCC pop_options 

Để làm cho nó di động, một cái gì đó như sau.

#define GCC_OPTIMIZE_AWARE (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__) 

#if GCC_OPTIMIZE_AWARE 
# pragma GCC push_options 
# pragma GCC optimize ("-O2") 
#endif 

Nó cần phải được bao bọc bởi vì với -Wall, phiên bản cũ của GCC không hiểu -Wno-unknown-pragma, và họ sẽ gây ra một biên dịch ồn ào. Phiên bản cũ hơn sẽ gặp phải trong lĩnh vực này, như GCC 4.2.1 trên OpenBSD.

Nhưng theo Markus Trippelsdorf trên When did 'pragma optimize' become available? từ mailing list GCC:

Đây là một ý tưởng tồi nói chung, bởi vì "pragma GCC tối ưu hóa" có nghĩa là như một trình biên dịch hỗ trợ gỡ lỗi mà thôi. Phải không được sử dụng trong mã sản xuất .

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