2011-12-12 73 views
5

Có cách nào để chỉ ra trình biên dịch mà bạn biết giá trị của một biến cụ thể phải nằm trong một phạm vi cụ thể tại một điểm nhất định trong mã, để hỗ trợ trình biên dịch có tối ưu hóa không? Tôi đang viết một thư viện mà làm cho nó có thể biết phạm vi của một số biến tại thời gian biên dịch, và nó sẽ được thuận tiện nếu nó bằng cách nào đó có thể truyền đạt thông tin này đến trình biên dịch để trình biên dịch có thể sử dụng nó để tối ưu hóa. Tôi muốn thêm hỗ trợ cho bất kỳ trình biên dịch nào mà nó sẽ hoạt động ngay cả khi nó không thể được thực hiện để làm việc cho tất cả chúng (có vẻ như một số thứ mà một số trình biên dịch có thể mở rộng, nhưng tôi chưa tìm thấy bất kỳ). Tôi biết tôi có thể viết một cái gì đó như thế này:Làm cách nào để truyền thông tin phạm vi tới trình biên dịch C++?

if(x < COMPILE_TIME_MIN or x > COMPILE_TIME_MAX) 
    return; 
// compiler will assume for code below that x is in range COMPILE_TIME_MIN..COMPILE_TIME_MAX 

Nhưng đó là kiểm tra thời gian chạy. Có lẽ có một số mẹo để làm cho trình biên dịch đưa ra giả định về phạm vi mà không cần kiểm tra này?

+2

Bạn có bất kỳ suy nghĩ nào về loại tối ưu hóa này sẽ giúp ích gì không? –

+0

Nếu bạn sử dụng mẫu, bạn thực sự có thể thực hiện kiểm tra thời gian biên dịch nếu tất cả thông tin của bạn được biết đến lúc biên dịch. –

+0

Bạn đang sử dụng cụm từ "trình biên dịch", nhưng bạn không bao giờ cho chúng tôi biết cái nào. Có lẽ bạn có nghĩa là một số phiên bản của g ++ hoặc Visual C++, nhưng điều đó không rõ ràng. Tối ưu hóa nói chung không được giải quyết bởi các tiêu chuẩn, vì vậy bất cứ điều gì bạn có thể có thể làm ở đây là thực hiện cụ thể. –

Trả lời

6

Bất kỳ "gợi ý" nào như vậy sẽ là trình biên dịch cụ thể.

Ví dụ: Visual C++ cho phép bạn cung cấp gợi ý như vậy bằng cách sử dụng the __assume intrinsic.

(trình biên dịch khác cũng có thể cung cấp intrinsics như vậy, nhưng tôi không đủ quen thuộc với các trình biên dịch khác để cung cấp thêm thông tin. Tham khảo tài liệu của trình biên dịch của bạn nếu bạn đang quan tâm.)

+3

Từ googling của riêng tôi, gcc 4.5 trở lên có thể chuyển thông tin này cùng với cú pháp tương tự bằng cách sử dụng '#define __assume (cond) làm {if (! (Cond)) __builtin_unreachable(); } trong khi (0) ' –

+0

@DrewDormann Thú vị. Tôi nghĩ sẽ tốt hơn nếu xác định một macro duy nhất '#define ASSUME_THIS_THING (x) ...' mở rộng thành '__assume (x)' trên Visual C++ và đoạn mã của bạn trên gcc. Tốt nhất là không xác định macro của riêng bạn bằng tên trình biên dịch dành riêng (như '__assume'). –

+0

Thật tuyệt vời. James, quan tâm để kết hợp thông tin của Drew vào câu trả lời của bạn? Sau đó, tôi sẽ đánh dấu là được chấp nhận. –

3

Đó không phải là tiêu chuẩn, nhưng với gcc, có một lệnh gọi là __builtin_expect, với các macro được xác định là likelyunlikely phục vụ mục đích của bạn. Xem ví dụ here nói về việc sử dụng chúng trong không gian hạt nhân, nhưng __builtin_expect là phần mở rộng gcc và có thể được sử dụng trong không gian người dùng (xem this question), ngay cả khi likelyunlikely không được xác định.

+0

Có lỗi đánh máy trong nhận xét ở trên: nó phải là '__builtin_expect'. GCC chỉ sử dụng kỳ vọng như một gợi ý: nó sẽ không tránh các trường hợp mà kỳ vọng không được đáp ứng. –

+0

@MattG, vâng tôi không biết làm thế nào tôi đã viết 'buildtin'! – Shahbaz

0

Tôi không biết về bất kỳ kỹ thuật biên dịch C++ nào có lợi dụng thông tin này, nhưng tôi biết về các kỹ thuật phân tích tĩnh khác nhau; những cách phổ biến để "nói" cái gì đó để những công cụ sẽ được thông qua assert s, ví dụ:

assert(x > COMPILE_TIME_MIN); 
assert(x < COMPILE_TIME_MAX); 

Nhưng thường là những công cụ này cũng sẽ có thể phân tích những thứ như "nếu có điều kiện" của mình, do đó không có nhu cầu đặc biệt để làm như vậy.

Ngoài ra, nếu phạm vi thực sự nhỏ, bạn cũng có thể biểu thị nó trong một biến có kích thước nhỏ hơn - ví dụ: bằng cách sử dụng ngắn hoặc char - và thêm COMPILE_TIME_MIN. Điều đó có thể giúp các công cụ như vậy, mặc dù tôi không biết về bản dịch.

Và cuối cùng, như trong tất cả các phương pháp tối ưu hóa, tôi khuyên bạn nên định hình trước mã của mình để xem đây có thực sự là nút cổ chai hay không. Ngoài ra, hãy nhớ rằng các trình biên dịch được thiết kế để tối ưu hóa mã "bình thường" - tối ưu hóa bằng tay chắc chắn có thể hữu ích, chỉ cần thực hiện cẩn thận.

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