簡體   English   中英

C ++:if()指針檢查是否已優化?

[英]C++: is the if() pointer check optimized?

以下代碼測試2個setter程序的呼叫的時鍾時間。 一個檢查空指針,一個不檢查。 編譯的-O3標志的程序輸出給出相同的時間:

  0.000000 ticks (0.000000 secs)
  0.000000 ticks (0.000000 secs)

使用-O0標志,​​時序差異仍然很小

  4250000.0000 ticks (4.25000 secs)
  4230000.0000 ticks (4.25000 secs)

是由編譯器在for循環中優化的嗎? 如果是這樣,應該如何針對兩者的效率差異測試“真實”世界場景?

class B {};
class A
{
public:
      void set( int a ) { a_ = a; }
      int get() const { return a_; }
private:
      int a_;
};

class A1

public:
      A1() : b_(0) {}

      void set( int a ) { if( b_ ) a_ = a; }
      int get() const { return a_; }

private:
      int a_;
      B* b_;
}; 


int main()
{
      const int n=1000000000;
      clock_t t0, t1;

      A a;
      A1 a1;

      t0 = clock();
      for( int i=0; i < n; ++i ) 
            a.set( i );
      t1 = clock();
      printf( "%f ticks (%.6f secs)\n", (double) t1-t0, ((double) t1-t0) / CLOCKS_PER_SEC );

      t0 = clock();
      for( int i=0; i < n; ++i ) 
            a1.set( i );
      t1 = clock();
      printf( "%f ticks (%.6f secs)\n", (double) t1-t0, ((double) t1-t0) / CLOCKS_PER_SEC );

      return 0;
}

檢查空指針幾乎可以肯定是一個時鍾周期的操作。 在任何現代處理器上,這將是二十億分之一秒。 我認為這超出了滴答計數器的分辨率(取決於平台,該分辨率為毫秒或微秒)。

如果您真的想知道,請在調試器中查看發出的匯編代碼。

-O3情況下的測量結果為0,因此顯然編譯器進行了優化,而不僅僅是空指針檢查。 它完全刪除了循環,原因是循環中生成的結果從未使用過。

您確實有a.get(); a1.get(); 在代碼中檢索循環中生成的值,但是同樣,這些函數調用的結果不涉及任何副作用,因此編譯器將其刪除。

如果將這些get()調用替換為clock()調用之后放置的打印語句(以確保時間測量中不包括IO),則會得到不同的結果(我從中刪除了aa1的實際值輸出):

2540000.000000 ticks (2.540000 secs)
0.000000 ticks (0.000000 secs)

因此,第一個循環現在執行一些實際操作,而第二個循環仍被優化(Clang 3.3)。 原因可能是a1._a的設置取決於指針,該指針已初始化為0 ,然后在循環中從未更改。 a1.set()的函數調用內聯到主循環中之后,編譯器可以很容易地看到a1._a的分配將永遠不會發生。


(注意:由於從未實際設置a1._a ,因此打印其值意味着打印從未初始化的變量的值。的確,我得到了一個看起來非常隨機的輸出,當然,嚴格來說,打印該值會調用未定義的值行為。)

暫無
暫無

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

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