dogz007 has asked for the wisdom of the Perl Monks concerning the following question:

I've created a new subclass of pdl's that are typically not square. I understand that pdl's are stored in column-major form in order to save memory (and speed?) in a C matrix format. Which brings me to my question: in an attempt to save memory, should I orient my pdl's such that number of columns is smaller than the number of rows, or vice versa? Computationally it does not matter, I would just need to wrap my mind around the fact that the matrices will be transposed when printed (unless I transpose them back). Perhaps an example would help. I ran a quick test in perldl which resulted in the following:

perldl> $a = zeroes 3,1000; perldl> $b = zeroes 1000,3; perldl> help vars PDL variables in package main:: Name Type Dimension Flow State Mem ---------------------------------------------------------------- $a Double D [3,1000] P 0.02Mb $b Double D [1000,3] P 0.02Mb

This of course would lead me to believe that it doesn't matter one way or the other. Perhaps one of you PDL experts out there could shed some light on the subject.

Replies are listed 'Best First'.
Re: Which pdl orientation saves memory
by dk (Chaplain) on Aug 22, 2007 at 09:40 UTC
    Back then when I messed with piddles in C, the 2-D memory layout was a plain X*Y matrix, without padding of any kind. If things haven't changed in the last years, the orientation indeed shouldn't matter.
Re: Which pdl orientation saves memory
by bart (Canon) on Aug 22, 2007 at 10:28 UTC
    In C, apart from padding (rounding up to multiples of 4 bytes — and for doubles, that typically occupy 8 bytes each, there won't be any padding), 2D arrays are actually stored as a flat single dimension array. That's why memory usage is identical.
      Thank you very much to both dk and bart. I guess this leaves me free to choose my own matrix orientation. When I'm done with this new subclass I plan to share it with the monks for feedback. Thanks again!

        The important thing is which dimension will you be iterating with the greatest frequency?

        PDL applies operations to whole piddles at a time. If you arrange your matrix so that the longest dimension is its first (leftmost) dimension, then the loop code at the assembler level is likely to be able to use auto-incrementing addressing modes, because the fastest changing dimension will be consecutive addresses. This will be faster, often much faster than if it has to add a large offset to calculate the next address each time. It will also likely benefit from greater cache coherency which again can have a significant impact upon performance.

        So if all else is equal to your algorithm, make the first (leftmost) dimension of your piddle the largest. See also the documentation of PDL implicit and explicit 'threading'. It goes right over my head, but seems to be applicable to this discussion.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.