簡體   English   中英

x86“ cmp”指令的奇怪行為

[英]strange behavior of x86 “cmp” instruction

這是代碼:

#include <iostream>
#include <time.h>

using namespace std;

#define ARR_LENGTH 1000000
#define TEST_NUM 0
typedef unsigned int uint;

uint arr[ARR_LENGTH];

uint inc_time(uint x) {
    uint y = 0, tm = clock();
    for (uint i = 0; i < x; i++) y++;
        return clock() - tm;
}

int main() {
    uint div = 0, mod = 0, tm = 0, overall = 0, inc_tm;
    srand(time(NULL));
    for (uint i = 0; i < ARR_LENGTH; i++) arr[i] = (uint)rand() + 2;

    tm = clock();
    for (uint i = 0; i < ARR_LENGTH - 1; i++)
        if (arr[i] % arr[i+1] != TEST_NUM) mod++;
    overall = clock() - tm;
    inc_tm = inc_time(mod);
    cout << "mods - " << mod << endl;
    cout << "Overall time - " << overall<< endl;
    cout << "   wasted on increment - " << inc_tm << endl;
    cout << "   wasted on condition - " << overall - inc_tm << endl << endl;

    tm = clock();
    for (uint i = 0; i < ARR_LENGTH - 1; i++)
        if (arr[i]/arr[i+1] != TEST_NUM) div++;
    overall = clock()-tm;
    inc_tm = inc_time(div);
    cout << "divs - " << div << endl;
    cout << "Overall time - " << overall << endl;
    cout << "   wasted on increment - " << inc_tm << endl;
    cout << "   wasted on condition - " << overall - inc_tm << endl << endl;

    return 0;
}

如果您使用的是Visual Studio,則只需在DEBUG(不是RELEASE)模式下進行編譯,如果您使用的是GCC,則要禁用無效代碼消除( -fno-dce ),否則某些代碼將無法工作。

因此,問題是:當您將TEST_NUM常數設置為非零(例如5)時,兩個條件(模和除)都幾乎同時執行,但是當您將TEST_NUM設置為0時,第二個條件執行TEST_NUM慢(最多3次!)。 為什么?

這是反匯編清單: 反匯編清單圖片http://img213.imageshack.us/slideshow/webplayer.php?id=wp000076.jpg

在0的情況下,使用test指令代替cmp X, 0但是即使將cmp X, 5 (在cmp X, 5的情況下)修補到cmp X, 0您也會看到它不會影響模運算,但是會影響除法運算

更改TEST_NUM常數時,請仔細觀察操作計數和時間如何變化。

如果有人可以,請說明如何發生?
謝謝。

TEST_NUM == 0的情況下,第一個條件很少為真。 分支預測將認識到這一點並預測條件始終為假。 該預測在大多數情況下都是正確的,因此很少需要執行昂貴的錯誤預測分支。

'TEST_NUM == 5'的情況幾乎相同:第一個條件很少為真。

對於第二條件abd TEST_NUM == 0 ,對於每個arr[i] < arr[i+1] ,除法的結果為零,其概率約為0.5。 對於分支預測器而言,這是最壞的情況-在每第二種情況下分支將被預測為錯誤。 平均而言,您將獲得錯誤的預測分支所需的一半時鍾周期(取決於體系結構,這可能在10至20個周期之間)。

如果您的值TEST_NUM == 5 ,則第二個條件現在很少為真,則概率約為0.1(此處不太確定)。 這是更好的“可預測的”。 通常,預測器將(幾乎)始終預測為假,其間有一些隨機的真實值,但這取決於處理器的內在條件。 但是無論如何,錯誤的預測分支得到的額外循環並不那么頻繁,每五分之一的情況下最糟。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM