gpt4 book ai didi

c++ - C++ 中的 vector 和数组

转载 作者:IT老高 更新时间:2023-10-28 23:02:43 25 4
gpt4 key购买 nike

C++ vector 和普通数组之间的性能差异已被广泛讨论,例如 herehere .通常讨论得出结论,当使用 [] 运算符访问 vector 和数组并且编译器启用内联函数时, vector 和数组在性能方面是相似的。这就是为什么预期的原因,但我遇到了一个似乎不正确的案例。下面几行的功能非常简单:获取一个 3D 体积,然后交换并应用某种 3D 小蒙版一定次数。根据 VERSION 宏,卷将被声明为 vector 并通过 at 运算符 (VERSION=2) 访问,声明为 vector 并访问通过 [] (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)我做错了什么,例如在编译时?或者我们真的应该期待 vector 和数组之间的差异吗?

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”。

关于c++ - C++ 中的 vector 和数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21253690/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com