2012-10-18 41 views
6

Khi cùng một đoạn mã được biên dịch với tối ưu hóa hoàn toàn vô hiệu hóa (g++ -O0) và sau đó một lần nữa với tối ưu hóa được kích hoạt đầy đủ (g++ -O3), làm thế nào có thể logic của chính mã nguồn được thay đổi?Làm thế nào tối ưu hóa trình biên dịch có thể ảnh hưởng đến logic mã?

Ví dụ, trình biên dịch có thể

Hai tối ưu hóa này làm cho mã hoạt động nhanh hơn mà không ảnh hưởng đến tính toàn vẹn của mã nguồn ban đầu. Bất kỳ mã nào chạy mà không có các tối ưu hóa này sẽ chạy với chúng được bật.

Nhưng tối ưu hóa trình biên dịch cũng có thể ảnh hưởng đến logic mã. Dưới đây là hai ví dụ mà tôi biết:

  • Removing copy constructors and assignment operators từ thời gian có thể loại bỏ các tác dụng phụ có thể xảy ra.
  • Sắp xếp lại số học có chứa các giá trị dấu phẩy động có thể ảnh hưởng đến lỗi dấu phẩy động (hy vọng yêu cầu đối số -ffast-math).

Tôi đã rất ngạc nhiên, và may mắn, để tìm hiểu về những điều này bởi vì chúng có thể trở thành tiềm năng rất lớn trong tình huống sai.

Vì vậy, tôi muốn biết, có bất kỳ trường hợp nào khác mà tối ưu hóa trình biên dịch C++ sẽ ảnh hưởng đến mã logic không? Tôi đang tìm kiếm thông tin cụ thể về C++ 11 (không có bất kỳ hành vi không xác định nào) theo trình biên dịch g ++, nhưng lời khuyên cho các trình biên dịch khác được chào đón.

+3

Đừng quên đề cập đến hành vi không xác định đó sẽ có nghĩa là mọi thứ xảy ra. – Mysticial

+0

Tôi tin rằng trình biên dịch cũng có thể 'không tính toán' công cụ mà không bao giờ được sử dụng sau này. Mặc dù điều này không thay đổi logic của mã của bạn, nhưng điều đó có thể không tốt nếu bạn đang đo lường hiệu suất. Tôi không chắc chắn về điều này mặc dù. – leo

+0

@leo Điểm tốt! Mặc dù, tôi luôn mong đợi việc biên dịch với tối ưu hóa sẽ hoạt động nhanh hơn, bởi vì đó là công việc của trình tối ưu hóa. – Ryan

Trả lời

8

Các "như nếu" Rule:

An thực hiện là miễn phí để bỏ qua bất kỳ yêu cầu của tiêu chuẩn quốc tế này càng lâu càng kết quả là, nếu như yêu cầu đã tuân, như xa có thể được xác định từ hành vi quan sát được của chương trình. Ví dụ, nhu cầu thực hiện thực tế không đánh giá một phần của biểu thức nếu nó có thể suy ra rằng giá trị của nó là không được sử dụng và không có tác dụng phụ nào ảnh hưởng đến hành vi quan sát của .

Tuy nhiên, tiêu chuẩn đề cập đến một tối ưu hóa được cho phép, và đó phá vỡ "như nếu" quy tắc:

Khi tiêu chí nhất định được đáp ứng, một thực hiện được phép bỏ qua bản sao/di chuyển xây dựng của một đối tượng lớp, ngay cả khi sao chép/di chuyển constructor và/hoặc destructor cho đối tượng có tác dụng phụ. Trong trường hợp này, việc triển khai xử lý nguồn và mục tiêu của hoạt động sao chép/di chuyển bị bỏ qua chỉ đơn giản là hai cách khác nhau để giới thiệu cho cùng một đối tượng và sự hủy diệt đối tượng đó xảy ra tại sau đó khi hai đối tượng sẽ bị phá hủy mà không cần tối ưu hóa.123 sự bỏ bớt này hoạt động sao chép/di chuyển, gọi là bản sao sự bỏ bớt, được cho phép trong các trường hợp sau (có thể được kết hợp để loại bỏ nhiều bản sao):

- trong một tuyên bố trở lại trong một hàm với một kiểu lớp trở lại , khi biểu thức là tên của đối tượng tự động không bay hơi (khác với hàm hoặc tham số điều kiện bắt) với cùng loại cvunqualified làm loại trả về hàm , có thể bỏ qua thao tác sao chép/di chuyển bằng cách xây dựng đối tượng tự động trực tiếp vào hàm trả về giá trị

- trong biểu thức ném, khi toán hạng là tên của đối tượng tự động không bay hơi (không phải là hàm hoặc tham số ) mà phạm vi của nó không mở rộng vượt ra ngoài phần cuối cùng của khối kèm theo (nếu có), các hoạt động sao chép/di chuyển từ các toán hạng để các đối tượng ngoại lệ (15,1) có thể được bỏ qua bởi xây dựng các đối tượng tự động trực tiếp vào đối tượng ngoại lệ

- khi một đối tượng lớp tạm thời mà có không bị ràng buộc với tham chiếu (12.2) sẽ được sao chép/di chuyển đến một đối tượng lớp có cùng loại cv không đủ điều kiện, thao tác sao chép/di chuyển có thể bị bỏ qua xây dựng các đối tượng tạm thời trực tiếp vào mục tiêu của bản sao bỏ qua /di chuyển

- khi trừ khai báo của một ngoại lệ handler (khoản 15) tuyên bố một đối tượng cùng loại (trừ cv tuyển) như đối tượng ngoại lệ (15.1), thao tác sao chép/di chuyển có thể được bỏ qua bằng cách xử lý tuyên bố ngoại lệ là bí danh cho đối tượng ngoại lệ nếu ý nghĩa của chương trình sẽ là không thay đổi ngoại trừ việc thực thi các hàm tạo và hàm hủy đối tượng được khai báo bởi tuyên bố ngoại lệ.

1

"Hành vi không xác định" là hành vi nơi triển khai tự do chọn bất kỳ hành vi có thể có nào. Trong những trường hợp như vậy, trình tối ưu hóa có thể ảnh hưởng đến lựa chọn được thực hiện.

Ví dụ đơn giản là thứ tự các đối số cho hàm được đánh giá. Các bản dựng không được tối ưu hóa có thể sử dụng Trái sang phải hoặc Phải sang Trái, trong khi các bản dựng được tối ưu hóa có thể đánh giá các đối số theo thứ tự "hỗn hợp". Một lý do chính đáng sẽ là tối đa hóa cơ hội cho Tối ưu hóa Subexpression chung giữa các đối số.

Nếu bất kỳ đối số nào trong số này có tác dụng phụ đáng chú ý, logic mã sẽ bị thay đổi, nhưng liệu đó có phải là lỗi khác nhau tùy từng trường hợp hay không.

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