Boost logo

Boost Users :

From: John C. Femiani (john.femiani_at_[hidden])
Date: 2008-08-07 11:10:20


joel falcou wrote:
> > I am actually interested about the iterators performance in multi-array
> > too, since their iterators seem to just wrap indexes. That _seems_
> like it
> > would be bad, but Idunno.
>
> iterator or pointer almost leads to the same performances (ina 5 to
> 10% margin maybe).
> The real error people keep doing is performing test on huge dataset
> without any cache friendly algorithm

Did you mean to say 'index or pointer'? It seems like the trend in image
processing is to avoid using indexes in the inner loop if at all possible.

As far as the cache-friendly issue, the example used the same memory and
the same access pattern.
I repeated the test on my system with mingw g++ 4.3.1 and the -O2 flag,
and I got similarly bad results ...

BUT I figured out why the performance was so bad in that case!
First, the poster did not use BOOST_DISABLE_ASSERTS, so the multi_array
was doing the extra checks.
Second, the results of the operation were never read, so the compiler
removed the whole 'Pointers' test.

With that macro defined, both loops are completely removed by the compiler.
If I make the result volatile, then the running times are:

Pointer....: 532
Multi_array: 593

HOWEVER, when I switch to using iterators & pointers for the inner loop
the penalty is a factor of 10 (not 10%, but 1000%)

Pointer....: 516
Multi_array: 5141

Again, same access pattern, same memory.

--John

//---modified code----

#define BOOST_DISABLE_ASSERTS

#include "windows.h"
#include <iostream>
#include "boost\multi_array.hpp"

using namespace std;
using namespace boost;

const size_t DimX = 2000;
const size_t DimY = 1500;
const size_t DimZ = 1;

volatile int iVal; //gbl volatile in an attempt to avoid optimizing away....

template<class It>
void test_helper(It begin, It end){
    while (begin != end)
        iVal = *begin++;
}
void testPointer(multi_array<int,3> &V3) {

    int * pInt = V3.data();
    for (size_t Z=0; Z<DimZ; ++Z)
        for (size_t Y=0; Y<DimY; ++Y)
            test_helper(pInt + (Z*DimY+Y)*DimX, pInt + (Z*DimY+Y)*DimX +
DimX);
}

void testMultiArray(multi_array<int,3> &V3) {

    for (size_t Z=0; Z<DimZ; ++Z)
        for (size_t Y=0; Y<DimY; ++Y)
            test_helper(V3[Z][Y].begin(), V3[Z][Y].end());
}
               
int main()
{
    multi_array<int,3> V3(extents[DimZ][DimY][DimX]);

    unsigned long time1, time2;
   
    time1 = GetTickCount();
    for (int q = 0; q < 100; ++q)
        testPointer(V3);
    time2 = GetTickCount();
    cout << "Pointer....: " << time2-time1 << endl;
   
   
    time1 = GetTickCount();
    for (int q = 0; q < 100; ++q)
        testMultiArray(V3);
    time2 = GetTickCount();
    cout << "Multi_array: " << time2-time1 << endl;

    return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net