我注意到我的 boost mutiarrays 与 STL Vector 相比表现非常糟糕。我遇到了之前提出的这个问题,其中最受欢迎的答案是
1) Boost 几乎和原生数组一样快
2) 您需要更改访问数据元素的顺序,以从 Boost MultiArray 中获得最佳性能。此外,您需要在发布模式下运行,而不是调试。
好吧,我做了所有这些,但我的 MultiArrays 的性能却很差。
我在这里发布我的代码:
A) 默认排序
#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
#include <stdio.h>
#include <conio.h>
#include <iostream>
int main(int argc, char* argv[])
{
const int X_SIZE = 400;
const int Y_SIZE = 400;
const int ITERATIONS = 500;
unsigned int startTime = 0;
unsigned int endTime = 0;
// Create the boost array
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
// Create the native array
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
//------------------Measure boost----------------------------------------------
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)
{
boostMatrix[x][y] *= 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
//------------------Measure native-----------------------------------------------
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)
{
nativeMatrix[x + (y * X_SIZE)] *= 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
return 0;
}
B) 倒序
#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
#include <stdio.h>
#include <conio.h>
#include <iostream>
int main(int argc, char* argv[])
{
const int X_SIZE = 400;
const int Y_SIZE = 400;
const int ITERATIONS = 500;
unsigned int startTime = 0;
unsigned int endTime = 0;
// Create the boost array
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
// Create the native array
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
//------------------Measure boost----------------------------------------------
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] *= 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
//------------------Measure native-----------------------------------------------
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)
{
nativeMatrix[x + (y * X_SIZE)] *= 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
return 0;
}
在所有可能的排列中,我的基准大致相同:
1) 对于本机代码:0.15s
2) 对于 Boost MultiArray : 1.0s
我使用的是 Visual Studio 2010。
我的问题是:鉴于我使用的是 Visual Studio,如何从 Boost MultiArrays 中获得良好的性能?
更新 :
我切换到 Visual Studio 2013。在那里,我启用了 Qvec-report2 编译器开关。非常有趣的是,当我编译时,我开始收到一条信息消息,说编译器无法矢量化。这是一个看起来几乎像警告的示例信息消息。对于最简单的代码,我收到了几条这样的消息。
--- 解析函数:void __cdecl `vector constructor iterator'(void * __ptr64,unsigned __int64,int,void * __ptr64 (__cdecl*)(void * __ptr64)) 1> D:\Workspace\test\Scrap\Scrap\Source .cpp:信息 C5002:由于原因“1301”,循环未矢量化
我认为这是为什么 Boost 多数组在我的 Visual Studio 上执行较慢而在 GCC 上执行正常的主要线索。鉴于这些额外的信息,您能想出解决问题的方法吗?
@Admins:请取消我之前回答的问题的标记。我进行了重大修改。