Thông thường, khi viết mã, tôi thấy mình sử dụng giá trị từ một hàm gọi cụ thể nhiều lần. Tôi nhận ra rằng một sự tối ưu hóa rõ ràng sẽ là nắm bắt các giá trị được sử dụng nhiều lần này trong các biến. này (pseudo code):Làm thế nào một trình biên dịch có thể áp dụng chức năng loại bỏ các hàm không tinh khiết?
function add1(foo){ foo + 1; }
...
do_something(foo(1));
do_something_else(foo(1));
trở thành:
function add1(foo){ foo + 1; }
...
bar = foo(1);
do_something(bar);
do_something_else(bar);
Tuy nhiên, làm điều này một cách rõ ràng làm cho mã dễ đọc hơn trong kinh nghiệm của tôi. Tôi cho rằng các trình biên dịch không thể thực hiện loại tối ưu hóa này nếu ngôn ngữ lựa chọn của chúng ta cho phép các hàm có tác dụng phụ.
Gần đây tôi đã xem xét điều này và nếu tôi hiểu chính xác, tối ưu hóa này là/có thể được thực hiện cho các ngôn ngữ trong đó chức năng phải thuần túy. Điều đó không làm tôi ngạc nhiên, nhưng được cho là điều này cũng có thể được thực hiện cho các chức năng không tinh khiết. Với một số tìm kiếm Google nhanh chóng tôi tìm thấy những đoạn: GCC 4.7 Fortran improvement
Khi thực hiện front-end-tối ưu hóa, tùy chọn -faggressive chức năng-loại trừ cho phép việc loại bỏ các hàm duplicate gọi ngay cả đối với các chức năng bất tịnh.
Compiler Optimization (Wikipedia)
Ví dụ, trong một số chức năng ngôn ngữ không được phép có tác dụng phụ. Do đó, nếu một chương trình thực hiện nhiều cuộc gọi đến cùng một hàm với cùng các đối số, trình biên dịch có thể ngay lập tức suy ra rằng kết quả của hàm chỉ cần được tính một lần. Trong các ngôn ngữ mà các chức năng được phép có các tác dụng phụ, một chiến lược khác là có thể. Trình tối ưu hóa có thể xác định chức năng nào không có tác dụng phụ và hạn chế tối ưu hóa như vậy đối với các chức năng miễn phí có hiệu lực phụ. Tối ưu hóa này chỉ có thể khi trình tối ưu hóa có quyền truy cập vào hàm được gọi.
Từ hiểu biết của tôi, điều này có nghĩa là trình tối ưu hóa có thể xác định khi nào hàm không hoặc không thuần túy và thực hiện tối ưu hóa này khi hàm. Tôi nói điều này bởi vì nếu một hàm luôn tạo ra cùng một đầu ra khi cho cùng một đầu vào, và là tác dụng phụ tự do, nó sẽ đáp ứng cả hai điều kiện được coi là thuần túy.
Hai đoạn trích này đưa ra hai câu hỏi cho tôi.
- Trình biên dịch có thể thực hiện tối ưu hóa này một cách an toàn nếu một hàm không thuần túy? (như trong -faggressive-chức năng loại bỏ)
- Làm thế nào một trình biên dịch có thể xác định xem một hàm là thuần khiết hay không? (Như trong chiến lược gợi ý trong bài viết Wikipedia)
và cuối cùng là:
- thể loại này của tối ưu hóa được áp dụng cho bất kỳ ngôn ngữ, hoặc chỉ khi điều kiện nhất định được đáp ứng?
- Tối ưu hóa này có đáng giá ngay cả đối với các chức năng cực kỳ đơn giản không?
- Chi phí lưu trữ và truy xuất giá trị từ ngăn xếp tăng lên bao nhiêu?
Tôi xin lỗi nếu đây là những câu hỏi ngu ngốc hoặc phi logic. Họ chỉ là một số điều tôi đã tò mò về thời gian gần đây. :)
Điều này được gọi là ** loại bỏ biểu hiện chung phổ biến ** http://en.wikipedia.org/wiki/Common_subexpression_elimination – leppie
Tài liệu cho tùy chọn GNU Fortran đó có vẻ thiếu, và tôi nghi ngờ nó chỉ tạo sai mã nếu hàm có tác dụng phụ không phải ngẫu nhiên. Việc đọc nhanh các hướng dẫn tùy chọn tạo mã cho GNU Fortran đã khiến tôi nghi ngờ nghiêm trọng chất lượng của việc triển khai của chúng - đặc biệt là những thứ như âm thầm đưa biến cục bộ lớn vào bộ nhớ tĩnh ... –