簡體   English   中英

C ++中的向量和數組

[英]Vectors and Arrays in C++

已經廣泛討論了C ++向量和普通數組之間的性能差異,例如這里這里 通常討論得出結論,當使用[]運算符訪問時,向量和數組在性能方面類似,並且編譯器啟用了內聯函數。 這就是預期的原因,但我遇到的情況似乎並非如此。 以下幾行的功能非常簡單:采用3D體積,交換並應用某種3D小面具一定次數。 根據VERSION宏,卷將被聲明為向量並通過at運算符( VERSION=2 )訪問,聲明為向量並通過[]VERSION=1 )訪問或聲明為簡單數組。

#include <vector>
#define NX 100
#define NY 100
#define NZ 100
#define H  1
#define C0 1.5f
#define C1 0.25f
#define T 3000

#if !defined(VERSION) || VERSION > 2 || VERSION < 0 
  #error "Bad version"
#endif 

#if VERSION == 2
  #define AT(_a_,_b_) (_a_.at(_b_))
  typedef std::vector<float> Field;
#endif 

#if VERSION == 1
  #define AT(_a_,_b_) (_a_[_b_])
  typedef std::vector<float> Field;
#endif 

#if VERSION == 0
  #define AT(_a_,_b_) (_a_[_b_])
  typedef float* Field;
#endif 

#include <iostream>
#include <omp.h>

int main(void) {

#if VERSION != 0 
  Field img(NX*NY*NY);
#else
  Field img = new float[NX*NY*NY];
#endif 


  double end, begin;
  begin = omp_get_wtime();  

  const int csize = NZ;
  const int psize = NZ * NX;
  for(int t  = 0; t < T; t++ ) {

    /* Swap the 3D volume and apply the "blurring" coefficients */
    #pragma omp parallel for
    for(int j = H; j < NY-H; j++ ) { 
      for( int i = H; i < NX-H; i++ ) {
        for( int k = H; k < NZ-H; k++ ) {
          int eindex = k+i*NZ+j*NX*NZ;
          AT(img,eindex) = C0 * AT(img,eindex) +
              C1 * (AT(img,eindex - csize) +
                    AT(img,eindex + csize) + 
                    AT(img,eindex - psize) + 
                    AT(img,eindex + psize) );
        }
      }
    }
  }

  end = omp_get_wtime();
  std::cout << "Elapsed "<< (end-begin) <<" s." << std::endl;

 /* Access img field so we force it to be deleted after accouting time */
 #define WHATEVER 12.f
 if( img[ NZ ] == WHATEVER ) { 
   std::cout << "Whatever" << std::endl;
 }


#if VERSION == 0
  delete[] img;
#endif 

}

可以預期代碼將執行相同的VERSION=1VERSION=0 ,但輸出如下:

  • 版本2:經過了6.94905秒。
  • 版本1:經過4.08626秒
  • 版本0:經歷了1.97576秒。

如果我在沒有OMP的情況下編譯(我只有兩個核心),我會得到類似的結果:

  • 版本2:經過10.9895秒。
  • 版本1:經過7.14674秒
  • 版本0:經過3.25336秒。

我總是使用GCC 4.6.3和編譯選項-fopenmp -finline-functions -O3進行編譯(我當然在沒有omp的情況下編譯時刪除了-fopenmp )我做錯了什么,例如編譯時? 或者我們真的應該期待向量和數組之間的差異嗎?

PS:我不能使用std :: array,因為我依賴的編譯器不支持C11標准。 使用ICC 13.1.2,我得到了類似的行為。

我嘗試了你的代碼,用chrono來計算時間。

我用clang(版本3.5)和libc ++編譯。

clang ++ test.cc -std = c ++ 1y -stdlib = libc ++ -lc ++ abi -finline-functions -O3

對於VERSION 0和VERSION 1,結果完全相同,沒有太大區別。 它們平均為3.4秒(我使用的是虛擬機,因此速度較慢)。

然后我嘗試了g ++(版本4.8.1),

g ++ test.cc -std = c ++ 1y -finline-functions -O3

結果顯示,對於VERSION 0,它是4.4秒(粗略地),對於VERSION 1,它是5.2秒(粗略地)。

然后我用libstdc ++嘗試了clang ++。

clang ++ test.cc -std = c ++ 11 -finline-functions -O3

瞧,結果又回到了3.4秒。

所以,它純粹是g ++的優化“bug”。

暫無
暫無

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

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