Gen*_*nís 13 c++ arrays vector
已经广泛讨论了C++向量和普通数组之间的性能差异,例如这里和这里.通常讨论的结论是,当使用[]运算符访问并且编译器启用内联函数时,向量和数组在性能方面类似.这就是预期的原因,但我遇到的情况似乎并非如此.以下几行的功能非常简单:采用3D体积并交换并应用某种3D小面具一定次数.根据VERSION宏的不同,卷将被声明为向量,并通过atoperator(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
}
Run Code Online (Sandbox Code Playgroud)
可以预期代码将使用VERSION=1和执行相同的操作VERSION=0,但输出如下:
如果我在没有OMP的情况下编译(我只有两个核心),我会得到类似的结果:
我总是使用GCC 4.6.3和编译选项编译-fopenmp -finline-functions -O3(我当然-fopenmp在没有omp的情况下编译时删除)是否有我做错的事情,例如编译时?或者我们真的应该期待向量和数组之间的差异吗?
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秒(大约)。
然后,我尝试了 clang++ 和 libstdc++。
clang++ test.cc -std=c++11 -finline-functions -O3
瞧,结果又回到了 3.4 秒。
所以,这纯粹是g++的优化“bug”。
| 归档时间: |
|
| 查看次数: |
345 次 |
| 最近记录: |