2015-05-02 31 views
6

Hãy xem xét các chức năng sau:Đi qua tài liệu tham khảo liên tục của các loại nguyên thủy như các đối số chức năng

template <class T, class Priority> 
void MutableQueue<T, Priority>::update(const T& item, const Priority& priority) 
{ 
    ... 
} 

Would trình biên dịch x86-64 hiện đại có đủ thông minh để vượt qua đối số ưu tiên theo giá trị chứ không phải là tài liệu tham khảo nếu các loại ưu tiên có thể phù hợp trong một đăng ký?

+1

tôi nghi ngờ như vậy, vâng. Tuy nhiên, nếu việc thực hiện được tiếp xúc với các mô-đun bên ngoài, nó phải đáp ứng các yêu cầu của ABI - trong trường hợp đó, một tham chiếu là một tham chiếu. Nói chung, bạn muốn tránh tham chiếu đến nguyên thủy - và có nhiều cách để làm điều đó. – davmac

+1

Đoán của tôi là nếu một thể hiện kiểu 'T' có thể vừa với thanh ghi, trình biên dịch sẽ chuyển qua bản sao. Nếu không, nó có lẽ sẽ vượt qua biến bằng con trỏ. –

+1

Tôi đã làm một bài kiểm tra đơn giản với trình biên dịch clang. Dường như trình biên dịch thực sự làm cho các tối ưu hóa. Về cơ bản nó tạo ra một phiên bản được tối ưu hóa (như nội tuyến chức năng hoặc truyền theo giá trị) và một phiên bản (có thể không được sử dụng và chỉ nằm trong mã) tuân thủ các yêu cầu của ABI. –

Trả lời

0

Điều này hoàn toàn phụ thuộc vào nền tảng và trình biên dịch và do đó, cách các đối số được chuyển đến một hàm.
Các chi tiết cụ thể này được xác định trong ABI của hệ thống mà chương trình chạy; một số có một số lượng lớn thanh ghi và do đó sử dụng chúng chủ yếu. Một số đẩy tất cả vào ngăn xếp. Một số kết hợp chúng lại với nhau thành tham số N-th.

Một lần nữa, đó là điều bạn không thể dựa vào; bạn có thể kiểm tra nó theo một vài cách. Ngôn ngữ C++ không có khái niệm về thanh ghi.

2

Như @black đã đề cập, tối ưu hóa là trình biên dịch và nền tảng phụ thuộc. Điều đó nói rằng, chúng tôi thường mong đợi một số tối ưu hóa xảy ra hàng ngày khi sử dụng trình biên dịch tối ưu hóa tốt. Ví dụ, chúng tôi tin tưởng vào chức năng nội tuyến, đăng ký phân bổ, chuyển đổi phép nhân liên tục và bộ phận để bit thay đổi khi có thể, vv

Để trả lời câu hỏi của bạn

Would trình biên dịch x86-64 hiện đại được thông minh đủ để chuyển đối số ưu tiên theo giá trị thay vì tham chiếu nếu loại ưu tiên có thể vừa với một thanh ghi?

Tôi sẽ dùng thử. Xem để tự của bạn:

Đây là mã:

template<typename T> 
T square(const T& num) { 
    return num * num; 
} 

int sq(int x) { 
    return square(x); 
} 

GCC -O3, -O2, và -O1 đáng tin cậy thực hiện điều này tối ưu hóa.

Clang 3.5.1, mặt khác, dường như không thực hiện tối ưu hóa này.

Bạn có nên đếm số về việc tối ưu hóa như vậy không? Không phải lúc nào, và không hoàn toàn - tiêu chuẩn C++ không nói gì về việc một sự tối ưu hóa như thế này có thể xảy ra. Trong thực tế, nếu bạn đang sử dụng GCC, bạn có thể 'mong đợi' tối ưu hóa sẽ diễn ra.

Nếu bạn hoàn toàn muốn đảm bảo rằng việc tối ưu hóa như vậy xảy ra, bạn sẽ muốn sử dụng template specialization.

+1

Việc tối ưu hóa thực hiện thay thế này có vẻ là '-fipa-sra'. Có vẻ như tiếng kêu không hỗ trợ nó. – dyp

+0

@dyp: đã sửa. – EyasSH

2

Trình biên dịch có thể thực hiện tối ưu hóa, nhưng không bắt buộc.

Để buộc để vượt qua "tốt nhất" loại, bạn có thể sử dụng tăng: http://www.boost.org/doc/libs/1_55_0/libs/utility/call_traits.htm

Thay const T& (nơi đi qua giá trị là đúng) bởi call_traits<T>::param_type.

Vì vậy, mã của bạn có thể trở thành:

template <class T, class Priority> 
void MutableQueue<T, Priority>::update(call_traits<T>::param_type item, 
             call_traits<Priority>::param_type priority) 
{ 
    ... 
} 
Các vấn đề liên quan