我对 blitz++、armadillo、boost::MultiArray 与以下代码进行了比较(借自一篇旧帖子)
#include <iostream>
using namespace std;
#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
#include <blitz/array.h>
#include <armadillo>
int main(int argc, char* argv[])
{
const int X_SIZE = 1000;
const int Y_SIZE = 1000;
const int ITERATIONS = 100;
unsigned int startTime = 0;
unsigned int endTime = 0;
// Create the boost array
//------------------Measure boost Loop------------------------------------------
{
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int x = 0; x < X_SIZE; ++x)
{
for (int y = 0; y < Y_SIZE; ++y)
{
boostMatrix[x][y] = 1.0001;
}
}
}
endTime = ::GetTickCount();
printf("[Boost Loop] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
}
//------------------Measure blitz Loop-------------------------------------------
{
blitz::Array<double, 2> blitzArray( X_SIZE, Y_SIZE );
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int x = 0; x < X_SIZE; ++x)
{
for (int y = 0; y < Y_SIZE; ++y)
{
blitzArray(x,y) = 1.0001;
}
}
}
endTime = ::GetTickCount();
printf("[Blitz Loop] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
}
//------------------Measure armadillo loop----------------------------------------
{
arma::mat matArray( X_SIZE, Y_SIZE );
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE; ++y)
{
for (int x = 0; x < X_SIZE; ++x)
{
matArray(x,y) = 1.0001;
}
}
}
endTime = ::GetTickCount();
printf("[arma Loop] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
}
//------------------Measure native loop----------------------------------------
// Create the native array
{
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE*X_SIZE; ++y)
{
nativeMatrix[y] = 1.0001;
}
}
endTime = ::GetTickCount();
printf("[Native Loop]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
delete[] nativeMatrix;
}
//------------------Measure boost computation-----------------------------------
{
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
for (int x = 0; x < X_SIZE; ++x)
{
for (int y = 0; y < Y_SIZE; ++y)
{
boostMatrix[x][y] = 1.0001;
}
}
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int x = 0; x < X_SIZE; ++x)
{
for (int y = 0; y < Y_SIZE; ++y)
{
boostMatrix[x][y] += boostMatrix[x][y] * 0.5;
}
}
}
endTime = ::GetTickCount();
printf("[Boost computation] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
}
//------------------Measure blitz computation-----------------------------------
{
blitz::Array<double, 2> blitzArray( X_SIZE, Y_SIZE );
blitzArray = 1.0001;
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
blitzArray += blitzArray*0.5;
}
endTime = ::GetTickCount();
printf("[Blitz computation] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
}
//------------------Measure armadillo computation-------------------------------
{
arma::mat matArray( X_SIZE, Y_SIZE );
matArray.fill(1.0001);
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
//matArray.fill(1.0001);
matArray += matArray*0.5;
}
endTime = ::GetTickCount();
printf("[arma computation] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
}
//------------------Measure native computation------------------------------------------
// Create the native array
{
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
for (int y = 0; y < Y_SIZE*X_SIZE; ++y)
{
nativeMatrix[y] = 1.0001;
}
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE*X_SIZE; ++y)
{
nativeMatrix[y] += nativeMatrix[y] * 0.5;
}
}
endTime = ::GetTickCount();
printf("[Native computation]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
delete[] nativeMatrix;
}
return 0;
}
在windows,VS2010上,结果是
[Boost Loop] Elapsed time: 1.217 seconds
[Blitz Loop] Elapsed time: 0.046 seconds
[arma Loop] Elapsed time: 0.078 seconds
[Native Loop]Elapsed time: 0.172 seconds
[Boost computation] Elapsed time: 2.152 seconds
[Blitz computation] Elapsed time: 0.156 seconds
[arma computation] Elapsed time: 0.078 seconds
[Native computation]Elapsed time: 0.078 seconds
在windows,intel c++上,结果是
[Boost Loop] Elapsed time: 0.468 seconds
[Blitz Loop] Elapsed time: 0.125 seconds
[arma Loop] Elapsed time: 0.046 seconds
[Native Loop]Elapsed time: 0.047 seconds
[Boost computation] Elapsed time: 0.796 seconds
[Blitz computation] Elapsed time: 0.109 seconds
[arma computation] Elapsed time: 0.078 seconds
[Native computation]Elapsed time: 0.062 seconds
奇怪的东西:
(1) with VS2010, native computation (including loop) is faster than native loop
(2) blitz loop behave so different under VS2010 and intel C++.
要使用 intel c++ 编译器编译 blitz++,blitz/intel/ 文件夹中需要一个名为 bzconfig.h 的文件。但是没有。我只是复制 blitz/ms/bzconfig.h 中的那个。这可能会给出非最佳配置。任何人都可以告诉我如何使用 intel c++ 编译器编译 blitz++?在手册中,它说运行 bzconfig 脚本以获取正确的 bzconfig.h。但我不明白这是什么意思。
非常感谢!
补充一些我的结论:
1. Boost multi array is the slowest.
2. With intel c++ compiler, native pointers are very fast.
3. With intel c++ compiler, armadillo can achieve the performance of native pointers.
4. Also test eigen, it is x0% slower than armadillo in my simple cases.
5. Curious about blitz++'s behavior in intel c++ compiler with proper configuration.
Please see my question.