我试图将boost :: multi_array的性能与本机动态分配的数组进行比较,使用以下测试程序:
#include#define _SCL_SECURE_NO_WARNINGS #define BOOST_DISABLE_ASSERTS #include int main(int argc, char* argv[]) { const int X_SIZE = 200; const int Y_SIZE = 200; const int ITERATIONS = 500; unsigned int startTime = 0; unsigned int endTime = 0; // Create the boost array typedef boost::multi_array 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; }
我得到以下结果:
[Boost] Elapsed time: 12.500 seconds [Native]Elapsed time: 0.062 seconds
我不敢相信multi_arrays慢得多.谁能发现我做错了什么?
我认为缓存不是问题,因为我正在写入内存.
编辑:这是一个调试版本.Per Laserallan建议我做一个发布版本:
[Boost] Elapsed time: 0.266 seconds [Native]Elapsed time: 0.016 seconds
更接近.但对我来说,16比1似乎仍然很高.
好吧,没有明确的答案,但我现在要继续使用本机数组离开我的真实代码.
接受Laserallan的答案,因为这是我测试中最大的缺陷.
谢谢大家.
在我的机器上使用
g++ -O3 -march=native -mtune=native --fast-math -DNDEBUG test.cpp -o test && ./test
我明白了
[Boost] Elapsed time: 0.020 seconds [Native]Elapsed time: 0.020 seconds
然而改变const int ITERATIONS
来5000
我得到
[Boost] Elapsed time: 0.240 seconds [Native]Elapsed time: 0.180 seconds
然后ITERATIONS
返回500
,但X_SIZE
并Y_SIZE
设置为400
我得到一个更显著差异
[Boost] Elapsed time: 0.460 seconds [Native]Elapsed time: 0.070 seconds
最后反转[Boost]
案件的内环,看起来像
for (int x = 0; x < X_SIZE; ++x) { for (int y = 0; y < Y_SIZE; ++y) {
和保管ITERATIONS
,X_SIZE
并Y_SIZE
以500
,400
和400
我得到
[Boost] Elapsed time: 0.060 seconds [Native]Elapsed time: 0.080 seconds
如果我也为[Native]
案例颠倒了内循环(因此在这种情况下它的顺序是错误的),我得到了,毫不奇怪,
[Boost] Elapsed time: 0.070 seconds [Native]Elapsed time: 0.450 seconds
我gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
在Ubuntu 10.10上使用
总之:
通过适当的优化 boost :: multi_array按预期完成其工作
您访问数据的顺序很重要
你的测试有缺陷.
在DEBUG构建中,boost :: MultiArray缺少它非常需要的优化传递.(远远超过本机阵列)
在RELEASE构建中,您的编译器将查找可以直接删除的代码,并且您的大多数代码都在该类别中.
您可能会看到的是优化编译器看到可以删除大多数或所有"本机阵列"循环的结果.你的boost :: MultiArray循环在理论上也是如此,但MultiArray可能足以打败你的优化器.
对您的测试平台进行这一小改动,您将看到更多真实的结果:= 2.345
用" *= 2.345
" 更改" "的出现并再次使用优化进行编译.这将阻止编译器发现每个测试的外部循环都是冗余的.
我做到了,速度比较接近2:1.
您正在构建发布或调试吗?
如果在调试模式下运行,则boost数组可能非常慢,因为它们的模板魔法没有正确内联,从而在函数调用中产生大量开销.我不确定如何实现多数组,所以这可能完全关闭:)
也许存储顺序也有一些差异,因此您可能会逐列存储图像并逐行写入.这会导致缓存行为不佳,并可能减慢速度.
尝试切换X和Y循环的顺序,看看你是否获得了任何东西.这里有关于存储订购的一些信息:http: //www.boost.org/doc/libs/1_37_0/libs/multi_array/doc/user.html
编辑:由于你似乎使用二维数组进行图像处理,你可能会对检查boosts图像处理库gil感兴趣.
它可能具有较少开销的数组,可以完美地适应您的情况.