Boost::multi_array performance question

Steve Fallows picture Steve Fallows · Jan 15, 2009 · Viewed 13k times · Source

I am trying to compare the performance of boost::multi_array to native dynamically allocated arrays, with the following test program:

#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;
}

I get the following results:

[Boost] Elapsed time: 12.500 seconds
[Native]Elapsed time:  0.062 seconds

I can't believe multi_arrays are that much slower. Can anyone spot what I am doing wrong?

I assume caching is not an issue since I am doing writes to memory.

EDIT: This was a debug build. Per Laserallan's suggest I did a release build:

[Boost] Elapsed time:  0.266 seconds
[Native]Elapsed time:  0.016 seconds

Much closer. But 16 to 1 still seems to high to me.

Well, no definitive answer, but I'm going to move on and leave my real code with native arrays for now.

Accepting Laserallan's answer because it was the biggest flaw in my test.

Thanks to all.

Answer

rodrigob picture rodrigob · Nov 19, 2010

On my machine using

g++ -O3 -march=native -mtune=native --fast-math -DNDEBUG test.cpp -o test && ./test

I get

[Boost] Elapsed time:  0.020 seconds
[Native]Elapsed time:  0.020 seconds

However changing const int ITERATIONS to 5000 I get

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

then with ITERATIONS back to 500 but X_SIZE and Y_SIZE set to 400 I get a much more significant difference

[Boost] Elapsed time:  0.460 seconds
[Native]Elapsed time:  0.070 seconds

finally inverting the inner loop for the [Boost] case so it looks like

    for (int x = 0; x < X_SIZE; ++x)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {

and keeping ITERATIONS, X_SIZE and Y_SIZE to 500, 400 and 400 I get

[Boost] Elapsed time:  0.060 seconds
[Native]Elapsed time:  0.080 seconds

If I invert the inner loop also for the [Native] case (so it is in the wrong order for that case), I get, unsurprisingly,

[Boost] Elapsed time:  0.070 seconds
[Native]Elapsed time:  0.450 seconds

I am using gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 on Ubuntu 10.10

So in conclusion:

  • With proper optimization boost::multi_array does its job as expected
  • The order on which you access your data does matter