Paul Herring wrote:
> On Fri, Mar 19, 2010 at 3:52 PM, Jimmy Johnson <[email protected]> wrote:
> [...]
>>> Yes.  One (or two) allocation(s) instead of many smaller ones.  Since
>>> you know exactly how many elements you need, a single allocation can be
>>> done.  Even if you did NOT know how many elements to allocate, it is
>>> almost always faster to precalculate how many elements, allocate the
>>> amount of memory needed, and then perform the actual manipulation of the
>>> memory.
>> Great!  How do I do that?
> 
> func1() - your method allocating row by row, then initialising cell by cell
> func2() - allocating it on one go , initialising cell by cell
> func3() - as func2() but only initialising row 0 cell by cell only,
> and copying that row to other rows
> 
> Beneath that is some profiling showing a 20% saving in func2() (the 15
> and 12 million numbers.) and 87% saving in func3() (2 million number)
> 
> [...@pjhdesktop /tmp]# cat x.cpp
> #include <stdio.h>
> #include <string.h>
> 
> 
> double** func1(long width, long height){
>         double** buffer;
>         long i, j;
>         buffer = new double* [width];
>         for (i = 0; i < width; i++) {
>                 buffer [i] = new double [height];
>         };
>         for (i = 0; i < width; i++) {
>                 for (j = 0; j < height; j++) {
>                         buffer[i][j] = -10000;
>                 };
>         };
>         return buffer;
> }

You should consider writing one more function that does two allocations 
and returns a double **.  The first allocation is for row pointers, the 
second allocation is the data.

(I always do [height][width], but whatever.  As long as it is consistent.)


> double* func2(long width, long height){
>         double* buffer;
>         long i, j;
>         buffer = new double [width*height];
>         for (i = 0; i < width; i++) {
>                 for (j = 0; j < height; j++) {
>                         buffer[i*j] = -10000;
>                 };
>         };
>         return buffer;
> }

Why the two for-loops?

double *buffer2 = buffer;
for (long size = width * height; size; size--)
{
        *buffer2 = -10000.0;
        buffer2++;
}

The memcpy() route is probably still faster but the integer to double 
conversion and multiplying i * j is unnecessary.  Paul, let's see some 
more valgrind output.  Get the folks excited about code profiling.  :)

(This code makes me cringe but the OP is after raw performance here. 
Also, I could have done the classic '*buffer2++ = -10000.0;' but I find 
that to be rather unreadable.  I like to balance speed with readability.)

-- 
Thomas Hruska
CubicleSoft President
Ph: 517-803-4197

*NEW* MyTaskFocus 1.1
Get on task.  Stay on task.

http://www.CubicleSoft.com/MyTaskFocus/

Reply via email to