Boost :: multi_array性能问题

Ste*_*ows 27 c++ performance boost boost-multi-array

我试图将boost :: multi_array的性能与本机动态分配的数组进行比较,使用以下测试程序:

#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS 
#include <boost/multi_array.hpp>

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<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;
}
Run Code Online (Sandbox Code Playgroud)

我得到以下结果:

[Boost] Elapsed time: 12.500 seconds
[Native]Elapsed time:  0.062 seconds
Run Code Online (Sandbox Code Playgroud)

我不敢相信multi_arrays慢得多.谁能发现我做错了什么?

我认为缓存不是问题,因为我正在写入内存.

编辑:这是一个调试版本.Per Laserallan建议我做一个发布版本:

[Boost] Elapsed time:  0.266 seconds
[Native]Elapsed time:  0.016 seconds
Run Code Online (Sandbox Code Playgroud)

更接近.但对我来说,16比1似乎仍然很高.

好吧,没有明确的答案,但我现在要继续使用本机数组离开我的真实代码.

接受Laserallan的答案,因为这是我测试中最大的缺陷.

谢谢大家.

rod*_*gob 33

在我的机器上使用

g++ -O3 -march=native -mtune=native --fast-math -DNDEBUG test.cpp -o test && ./test
Run Code Online (Sandbox Code Playgroud)

我明白了

[Boost] Elapsed time:  0.020 seconds
[Native]Elapsed time:  0.020 seconds
Run Code Online (Sandbox Code Playgroud)

然而改变const int ITERATIONS5000我得到

[Boost] Elapsed time:  0.240 seconds
[Native]Elapsed time:  0.180 seconds
Run Code Online (Sandbox Code Playgroud)

然后ITERATIONS返回500,但X_SIZEY_SIZE设置为400我得到一个更显著差异

[Boost] Elapsed time:  0.460 seconds
[Native]Elapsed time:  0.070 seconds
Run Code Online (Sandbox Code Playgroud)

最后反转[Boost]案件的内环,看起来像

    for (int x = 0; x < X_SIZE; ++x)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
Run Code Online (Sandbox Code Playgroud)

和保管ITERATIONS,X_SIZEY_SIZE500,400400我得到

[Boost] Elapsed time:  0.060 seconds
[Native]Elapsed time:  0.080 seconds
Run Code Online (Sandbox Code Playgroud)

如果我也为[Native]案例颠倒了内循环(因此在这种情况下它的顺序是错误的),我得到了,毫不奇怪,

[Boost] Elapsed time:  0.070 seconds
[Native]Elapsed time:  0.450 seconds
Run Code Online (Sandbox Code Playgroud)

gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5在Ubuntu 10.10上使用

总之:

  • 通过适当的优化 boost :: multi_array按预期完成其工作
  • 您访问数据的顺序很重要


Dre*_*ann 11

你的测试有缺陷.

  • 在DEBUG构建中,boost :: MultiArray缺少它非常需要的优化传递.(远远超过本机阵列)
  • 在RELEASE构建中,您的编译器将查找可以直接删除的代码,并且您的大多数代码都在该类别中.

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

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

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


Las*_*lan 8

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

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

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

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

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

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