2010-06-30 56 views
6

Tôi hiện đang có các hàm nội tuyến gọi một hàm nội tuyến khác (một hàm 4 dòng lớn đơn giản getAbs()). Tuy nhiên, tôi phát hiện ra bằng cách tìm đến mã bộ mã hóa mà các hàm nội tuyến "lớn" được inlined tốt, nhưng trình biên dịch sử dụng bước nhảy bl để gọi hàm getAbs().nội tuyến một chức năng bên trong một hàm nội dòng khác trong C

Không thể nội dòng một hàm trong hàm nội tuyến khác? Bằng cách này, đây là mã nhúng, chúng tôi không sử dụng các thư viện chuẩn.

Chỉnh sửa: Trình biên dịch là WindRiver và tôi đã kiểm tra rằng nội tuyến sẽ có lợi (4 hướng dẫn thay vì + -40).

+0

Bạn đang sử dụng trình biên dịch nào? Có nhiều cách để buộc nội tuyến. Tôi đoán bạn đã lược tả mã của bạn và khá tự tin rằng nội tuyến sẽ có lợi. Trong GCC, điều này có thể được thực hiện với __attribute __ ((always_inline)). – stinky472

+0

Tôi có thể hỏi tại sao bạn quan tâm đến những quyết định mà trình biên dịch đã thực hiện? Bạn đã lược tả mã và tìm thấy chi phí của lệnh nhảy một lần đó là giết chết hiệu suất? – JeremyP

Trả lời

8

Tùy thuộc vào trình biên dịch bạn đang sử dụng, bạn có thể khuyến khích trình biên dịch ít miễn cưỡng hơn, ví dụ: với gcc, bạn có thể sử dụng __attribute__ ((always_inline)), với Intel ICC bạn có thể sử dụng icc -inline-level=1 -inline-forceinline và với gcc của Apple, bạn có thể sử dụng gcc -obey-inline.

7

Từ khóa inline là một đề xuất cho trình biên dịch, không có gì khác. Bạn có thể tự do đưa đề xuất đó lên tàu, hoàn toàn bỏ qua nó hoặc thậm chí nói dối bạn và nói rằng nó đang thực hiện nó trong khi nó thực sự không.

Cách duy nhất để buộc mã nội tuyến là, tốt, hãy viết nội tuyến. Nhưng, ngay cả, sau đó trình biên dịch có thể quyết định nó biết tốt hơn và quyết định chuyển nó sang một chức năng khác. Nó có rất nhiều thời gian trong việc tạo ra mã thực thi cho nguồn cụ thể của bạn, miễn là nó không thay đổi ngữ nghĩa của nó.

Trình biên dịch hiện đại có nhiều khả năng tạo mã tốt hơn so với hầu hết các nhà phát triển sẽ làm thủ công trong lắp ráp. Tôi nghĩ rằng từ khóa inline nên đi theo cùng một đường dẫn với từ khóa register.

Nếu bạn đã thấy đầu ra của gcc ở mức tối ưu hóa điên rồ của nó, bạn sẽ hiểu tại sao. Nó đã tạo ra mã mà tôi không thể mơ ước được, và điều đó đã khiến tôi mất nhiều thời gian để hiểu.

Ngoài ra, hãy kiểm tra this để biết những gì tối ưu hóa mà gcc thực sự có, bao gồm nhiều nội dung có chứa nội dung "nội tuyến" hoặc "nội tuyến".

+0

Tôi muốn mạo hiểm đoán và nói rằng từ khóa đã được thêm vào khi nhiệm vụ tìm ra liệu chức năng có thể được inline hơi quá lớn đối với trình biên dịch (hoặc chức năng khôn ngoan hoặc thời gian), nhưng trình biên dịch ngày nay có lẽ có khả năng tự tìm ra điều này, ngay cả khi từ khóa nội tuyến không có mặt. Chỉ là một đoán mặc dù. –

+0

Tôi muốn nói đó là một dự đoán khá an toàn. Xem cập nhật của tôi. – paxdiablo

+0

Gcc có hỗ trợ tối ưu hóa dựa trên hồ sơ không? Khi không sử dụng chúng, nó có ý nghĩa rất nhiều để gợi ý tại gcc nơi inline có thể giúp đỡ. Điều này dựa trên kiến ​​thức về việc liệu chức năng này có được gọi là * lot * hay không, cái gì mà trình biên dịch thông minh nhất vẫn không thể biết được. – Peaker

1

@gramm: Có một vài trường hợp trong đó nội tuyến không nhất thiết là lợi ích của bạn. Hầu hết các trình biên dịch sử dụng một số chẩn đoán rất tiên tiến để xác định thời điểm nội tuyến. Khi thảo luận nội tuyến, ý tưởng đơn giản nhất là, hãy tin tưởng trình biên dịch của bạn để tạo ra mã nhanh nhất.

-1

Tôi sẽ đề nghị rằng nếu hàm getAbs() của bạn (có vẻ như giá trị tuyệt đối nhưng bạn thực sự cần hiển thị mã với câu hỏi ...) dài 4 dòng, thì bạn có nhiều tối ưu hơn để lo lắng về việc liệu mã được nội tuyến hay không.

+0

Hoặc bạn đang nói rằng bất kỳ chi phí nào của việc gọi hàm là ít quan trọng đối với các chức năng ngắn, hoặc bạn đang nói rằng có các hàm ngắn là một điều xấu, theo cách bạn nhận được -1 –

+0

Không, tôi nói rằng việc thực hiện kém 'abs()' là một hiệu suất lớn hơn nhiều so với trình biên dịch không inline nó. (Và trong thực tế, trình biên dịch có thể làm điều đúng đắn bằng cách không gạch chân nó ..) –

+0

Giống như Pete. Có 50 hướng dẫn thay vì 5 là một chi phí rất lớn, và nó thường trở nên đáng chú ý khi được sử dụng trong một vòng lặp. Tôi không chắc chắn nếu bạn đang sử dụng để làm việc với vi điều khiển. – gramm

0

Gần đây tôi đã có một vấn đề rất giống nhau, đọc bài đăng này đã cho tôi một ý tưởng kỳ quặc. Tại sao không có một trình biên dịch đơn giản trước khi biên dịch (một reg ex đơn giản nên thực hiện công việc), trình phân tích cú pháp mã phân tích cú pháp hàm gọi để thực sự đặt mã nguồn trực tuyến. sử dụng thẻ chẳng hạn như/nội tuyến// end_of_inline/để bạn có thể sử dụng các tính năng ide thông thường (nếu bạn đang sử dụng ide) Bao gồm điều này trong quá trình xây dựng của bạn, theo cách đó bạn cũng có lợi thế về khả năng đọc như loại bỏ các trình biên dịch giả định rằng bạn chỉ là một nhà phát triển giỏi nhất và không hiểu khi nào trực tuyến.

Tuy nhiên trước khi thử điều này, bạn có lẽ nên đi qua các tùy chọn trình biên dịch dòng lệnh.

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