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/