我正在撰寫一個包含一些狀態變數的回圈。
int MyFunc(){
int state_variable_1 = 0;
int state_variable_2 = 12;
while(state_variable_1 != state_variable_2){
BodyOfWhileLoop(state_variable_1, state_variable_2);
}
}
如您所見,我在一個單獨的函式中撰寫了 while 回圈的主體,BodyOfWhileLoop. 這是為了保持代碼干凈并有助于除錯。
BodyOfWhileLoop將需要修改state_variable_1和 state_variable_2。我可以通過參考傳遞這些,例如,
void BodyOfWhileLoop(int& state_variable_1, int& state_variable_2);
這在功能上正是我想要的,但是,每次在函式體中使用狀態變數都需要取消參考(我相信)。我可以做這樣的事情:
void BodyOfWhileLoop(int& state_variable_1_ref, int& state_variable_2_ref){
int state_variable_1_copy = state_variable_1_ref;
int state_variable_2_copy = state_variable_2_ref;
// Do stuff with state variables
state_variable_1_ref = state_variable_1_copy;
state_variable_2_ref = state_variable_2_copy;
}
我認為有兩件事是正確的:
- 復制狀態變數會消耗記憶體,因為您為復制分配了空間。
BodyOfWhileLoop不復制狀態變數將花費時間,因為每次訪問狀態變數時都會在正文中進行額外的取消參考。
所以我有兩個問題:
- If the compiler inlined
BodyOfWhileLoop, would it still create astate_variable_1_refandstate_variable_2_ref(requiring a dereference to access theints)? Would the cost of accessingstate_variable_1be the same as accessing it withinMyFunc? - Are there alternative solutions I have not seen?
uj5u.com熱心網友回復:
不,他們沒有。演示:https ://godbolt.org/z/qc1ne7ezM 。
參考通常在底層實作為指標(盡管它們并非必須如此)。一旦函式被行內,編譯器將消除間接。在 LLVM 中,此優化是作為SROA的一部分執行的。
任何只有一個呼叫點的函式都應該由優化器行內,但請注意,如果一個函式具有外部鏈接,編譯器可能不會行內它:它可以在其他翻譯單元中使用,因此編譯器不知道它只使用了一次。為避免這種情況,請將其標記為static或inline,或使用鏈接時優化。
uj5u.com熱心網友回復:
C 標準不要求 C 編譯器以任何特定方式生成編譯后的代碼。C 標準規定了格式良好的 C 代碼的結果,而編譯器如何執行此操作完全取決于編譯器。沒有兩個 C 編譯器是相同的,不同的 C 編譯器可能會采用不同的方法,并從中等復雜度的 C 程式生成不同的編譯代碼。
此外,越來越多的 C 編譯器已經發展到實作新的鏈接時優化技術,這些技術將可能的優化范圍擴展到了傳統上可能的范圍之外,直到這一點。
通常,允許 C 編譯器實作任何沒有明顯效果的優化。如果您的 C 編譯器可以向自己證明您所考慮的優化沒有可觀察到的效果,那么您的 C 編譯器可以(但沒有義務)實作它。
編譯器是否最終進行此優化或任何其他優化完全取決于編譯器,最終結果也可能因編譯選項而異。因此,對于此類問題沒有明確的答案,除了編譯代碼然后檢查生成的編譯機器代碼以查看您的編譯器目錄。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/438343.html
