2012-09-22 30 views
9

Tiêu chuẩn không chỉ định thứ tự đánh giá các đối số với dòng này:Tại sao thứ tự đánh giá cho các tham số chức năng không được chỉ định trong C++?

Thứ tự đánh giá đối số không được chỉ định.

Better mã có thể được tạo ra trong sự vắng mặt của những hạn chế về trình tự đánh giá biểu

hàm ý?

Hạn chế trong việc yêu cầu tất cả các trình biên dịch để đánh giá các đối số hàm Trái sang phải chẳng hạn như thế nào? Những loại trình tối ưu hóa nào thực hiện bởi vì đặc tả không xác định này?

+4

Cho phép trình biên dịch sắp xếp lại đánh giá các toán hạng thêm nhiều chỗ cho tối ưu hóa. – Mysticial

+1

@Mysticial: Ngạc nhiên như nó có thể nhìn, đó phải là một câu trả lời, và thực sự là * chấp nhận * câu trả lời! –

+0

Các trình tối ưu hóa thực hiện các loại trình tối ưu hóa nào? – unj2

Trả lời

25

Cho phép trình biên dịch sắp xếp lại đánh giá các toán hạng thêm nhiều chỗ cho tối ưu hóa.

Dưới đây là ví dụ được tạo thành hoàn toàn cho mục đích minh họa.

Giả sử bộ vi xử lý có thể:

  • Issue 1 hướng dẫn mỗi chu kỳ.
  • Thực hiện phép cộng trong 1 chu kỳ.
  • Thực hiện phép nhân trong 3 chu kỳ.
  • Có thể thực thi các phép cộng và phép nhân cùng một lúc.

Bây giờ giả sử bạn có một cuộc gọi chức năng như sau:

foo(a += 1, b += 2, c += 3, d *= 10); 

Nếu bạn đã thực hiện từ trái sang bên phải này trên một bộ xử lý mà không cần OOE:

Cycle - Operation 
0  - a += 1 
1  - b += 2 
2  - c += 3 
3  - d *= 10 
4  - d *= 10 
5  - d *= 10 

Bây giờ nếu bạn cho phép trình biên dịch sắp xếp lại chúng: (và bắt đầu phép nhân trước)

Cycle - Operation 
0  - d *= 10 
1  - a += 1, d *= 10 
2  - b += 2, d *= 10 
3  - c += 3 

Vì vậy, 6 chu kỳ so với 4 chu kỳ.

Một lần nữa điều này hoàn toàn bị giả tạo. Các bộ xử lý hiện đại phức tạp hơn nhiều. Nhưng bạn hiểu ý rồi đấy.

1

Đây là một ví dụ đơn giản. Giả sử bạn có một cuộc gọi chức năng như sau:

// assume that p is a pointer to an integer 
foo(*p * 3, bar(), *p * 3 + 1); 

Trình biên dịch cần phải dereference p hai lần (và làm một số tính toán dựa trên kết quả) và gọi bar một lần. Nếu trình biên dịch thông minh, nó có thể sắp xếp lại đánh giá thành

int temp = *p * 3; 
foo(temp, bar(), temp + 1); 

Bằng cách đó, nó phải thực hiện "dereference, multiply by 3" chỉ một lần. Điều này được gọi là loại trừ phổ biến subexpression.

+1

Để công bằng, ngay cả các ngôn ngữ đảm bảo thứ tự đánh giá cũng có thể làm điều này, miễn là chúng có thể phân loại chứng minh rằng giá trị của 'p' không thể thay đổi ở giữa. Tất nhiên, với mô hình bộ nhớ C là khá nhiều không thể đảm bảo, đó có lẽ là lý do tại sao thứ tự không xác định của đánh giá là cần thiết để đạt được tối ưu hóa này. – Joey

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