当前位置:  开发笔记 > 编程语言 > 正文

Boost :: multi_array性能问题

如何解决《Boost::multi_array性能问题》经验,为你挑选了3个好方法。

我试图将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的答案,因为这是我测试中最大的缺陷.

谢谢大家.



1> rodrigob..:

在我的机器上使用

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 ITERATIONS5000我得到

[Boost] Elapsed time:  0.240 seconds
[Native]Elapsed time:  0.180 seconds

然后ITERATIONS返回500,但X_SIZEY_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_SIZEY_SIZE500,400400我得到

[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按预期完成其工作

您访问数据的顺序很重要



2> Drew Dormann..:

你的测试有缺陷.

在DEBUG构建中,boost :: MultiArray缺少它非常需要的优化传递.(远远超过本机阵列)

在RELEASE构建中,您的编译器将查找可以直接删除的代码,并且您的大多数代码都在该类别中.

您可能会看到的是优化编译器看到可以删除大多数或所有"本机阵列"循环的结果.你的boost :: MultiArray循环在理论上也是如此,但MultiArray可能足以打败你的优化器.

对您的测试平台进行这一小改动,您将看到更多真实的结果:= 2.345用" *= 2.345" 更改" "的出现并再次使用优化进行编译.这将阻止编译器发现每个测试的外部循环都是冗余的.

我做到了,速度比较接近2:1.



3> Laserallan..:

您正在构建发布或调试吗?

如果在调试模式下运行,则boost数组可能非常慢,因为它们的模板魔法没有正确内联,从而在函数调用中产生大量开销.我不确定如何实现多数组,所以这可能完全关闭:)

也许存储顺序也有一些差异,因此您可能会逐列存储图像并逐行写入.这会导致缓存行为不佳,并可能减慢速度.

尝试切换X和Y循环的顺序,看看你是否获得了任何东西.这里有关于存储订购的一些信息:http: //www.boost.org/doc/libs/1_37_0/libs/multi_array/doc/user.html

编辑:由于你似乎使用二维数组进行图像处理,你可能会对检查boosts图像处理库gil感兴趣.

它可能具有较少开销的数组,可以完美地适应您的情况.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有