我的教授曾經說過,if 陳述句相當慢,應該盡可能避免。我正在用 OpenGL 制作游戲,我需要很多游戲。在我的測驗中,通過短路用 AND 替換 if 陳述句是可行的,但它更快嗎?
bool doSomething();
int main()
{
int randomNumber = std::rand() % 10;
randomNumber == 5 && doSomething();
return 0;
}
bool doSomething()
{
std::cout << "function executed" << std::endl;
return true;
}
我的意圖是在我的渲染器的繪制函式中使用它。我的模型應該有標志,如果標志為真,則應該執行某個函式。
uj5u.com熱心網友回復:
if 陳述句相當慢,應盡可能避免。
這是錯誤的和/或誤導性的。大多數關于程式緩慢的簡化陳述都是錯誤的。這個答案可能也有問題。
C 陳述句沒有可以歸因于它們的速度。重要的是編譯程式的速度。這包括匯編語言指令;不是 C 陳述句。
可能更正確的說法是分支指令可能相對較慢(在現代的超標量 CPU 架構上)(當無法很好地預測分支時)(取決于您要比較的內容;有很多事情要多得多昂貴的)。
randomNumber == 5 && doSomething();
if 陳述句通常被編譯到使用分支指令的程式中。短路邏輯與運算也經常被編譯到使用分支指令的程式中。用邏輯與運算子替換 if 陳述句并不是讓程式更快的靈丹妙藥。
如果您要比較由邏輯與生成的程式和它被替換為的相應程式if (randomNumber == 5),您會發現優化器看穿了您的技巧并在兩種情況下都生成了相同的程式集。
我的模型應該有標志,如果標志為真,則應該執行某個函式。
為了避免分支,必須改變前提。與其遍歷所有模型的序列、檢查標志和有條件地呼叫函式,不如創建一個應呼叫函式的所有模型的序列,對其進行迭代,然后無條件地呼叫函式 -> 無分支。這種替代方案更快嗎?維護資料結構肯定有一些開銷,分支預測器可能使這變得不必要。唯一確定的方法是測量程式。
uj5u.com熱心網友回復:
我同意上面的評論,在幾乎所有實際情況下,可以if毫不猶豫地盡可能多地使用 s 。
我也同意,對于初學者來說,在優化上浪費精力并不是一個重要的問題,并且使用邏輯運算子可能會發出類似于ifs 的代碼。
但是 - 這里有一個與一般分支相關的有效問題,因此歡迎有興趣的人繼續閱讀。
現代 CPU 使用我們所說的指令流水線。
無需深入了解技術細節:
在每個 CPU 內核中都有一定程度的并行性。每條匯編指令都由若干階段組成,在執行當前指令的同時,也在一定程度上準備下一條指令。這稱為指令流水線。
這個概念通常被任何型別的分支打破,if特別是條件句(s)。
確實有一種分支預測機制,但它只是在一定程度上起作用。
因此,盡管在大多數情況下ifs 是完全可以的,但在某些情況下應該考慮到它。與往常一樣,在優化方面,應該仔細分析。
以下面這段代碼為例(類似的東西在影像處理和其他實作中很常見):
unsigned char * pData = ...; // get data from somewhere
int dataSize = 100000000; // something big
bool cond = ...; // initialize some condition for relevant for all data
for (int i = 0; i < dataSize; i, pData)
{
if (cond)
{
*pData = 2; // imagine some small calculation
}
else
{
*pData = 3; // imagine some other small calculation
}
}
這樣做可能會更好(即使它包含從軟體工程的角度來看是邪惡的重復):
if (cond)
{
for (int i = 0; i < dataSize; i, pData)
{
*pData = 2; // imagine some small calculation
}
}
else
{
for (int i = 0; i < dataSize; i, pData)
{
*pData = 3; // imagine some other small calculation
}
}
我們仍然有一個,if但它導致可能只分支一次。
在某些 [罕見] 情況下(需要如上所述的分析),即使是這樣的事情也會更有效率:
for (int i = 0; i < dataSize; i, pData)
{
*pData = (2 * cond 3 * (!cond));
}
我知道這并不常見,但幾年前我遇到了特定的硬體,其中 2 次乘法和 1 次加法與否定的成本低于分支的成本(由于指令管道的重置)。此“技巧”還支持對資料的不同部分使用不同的條件值。
底線: if s 通常是可以的,但很高興知道有時會有成本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/475004.html
上一篇:如何修復我的抓鉤腳本錯誤
