June 19, 2006

Hasan Aljudy wrote:
> 
> 
> Jarrett Billingsley wrote:
>> "Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:e751ri$2709$1@digitaldaemon.com...
>>
>>
>>>> btw. How do I reset all the data of a rectangular array?
>>>> something like:
>>>> tiles[][]=0;
>>
>>
>> Damn news client.  Ctrl + Enter posts, apparently.
>>
>> I assume your array is of a static size (thus making it a rectangular
>> array).  You can do this:
>>
>> foreach(/* auto */ a; tiles)
>>     a[] = 0;
>>
>> (I just put the /* auto */ in there to let me know when I'm using the dirty, nonobvious foreach index type inference)
>>
>> Or, and this is a little hackish, but you can take advantage of the layout of rectangular arrays, which is a single block of memory:
>>
>> ((cast(TILE*)tiles.ptr)[0 .. TILEW * TILEH])[] = 0;
>>
>> Basically, you're converting the rectangular array type into a linear array type, and setting all those elements to 0.  I would imagine this would be somewhat faster, since it's doing one block set, rather than one block for each row.
>>
> 
> 
> This won't work if the array is dynamically allocated.
> 
> Dynamic 2D arrays in are not exactly c-style rectangular arrays; they are arrays of pointers to arrays of pointers. In C# they call this "jagged arrays".
> 
> see:
> http://www.digitalmars.com/d/arrays.html
> scroll down to "Rectangular Arrays"
> <quote>
> (Dynamic arrays are implemented as pointers to the array data.) Since
> the arrays can have varying sizes (being dynamically sized), this is
> sometimes called "jagged" arrays. Even worse for optimizing the code,
> the array rows can sometimes point to each other! Fortunately, D static
> arrays, while using the same syntax, are implemented as a fixed
> rectangular layout
> </quote>
> 
>> I assume your array is of a static size
> 
> Is there a way in D to test for this? anything like:
> assert( isStaticallyAllocated( tiles ) );
> would be nice in this case, but I don't think it's possible.
> 
> I would rather use a one-dimensional array and treat it as if it were rectangular. Maybe a little template magic can help ease this task.
> 

What I did when I needed this was to make a small templated struct that implemented opIndex and opIndexAssign, which took care of the two-dimensional lookups for me.  The code to do this is pretty much trivial, but this way you can add bounds checking, and since the code is so short, `-release -O -inline` should expand the function out for you.

A nice advantage to using a struct (or even a class) is that you can then go and do all sorts of evil things like clipping, strides and other fun things.

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
June 19, 2006
I did your insanity test.. And here there was no significant speed difference
(also none with -O)

But why do you use:
arr = cast(TILE (*)[TILEW][TILEH])calloc(TILEW*TILEH,TILE.sizeof);

Was that only for the size limit?
I just used:
TILE[TILEW][TILEH] arr;

TILEW && TILEH == 250

(Still the same speed)

Why this is the limit I don't understand, 16MB should be the limit, right?



June 19, 2006
I soo hope I did not ask for something strange, but I thought rectangular arrays would just be things like:

int arr[250][250];

Is there something I'm missing? Something that D can't do. Some speed issue?

int ar[100][50][25];

Also works, although there is this limit to its size I don't uderstand

int ar[250][250][10]; should in no way exceed 16MB (more like < 3MB)

(see the speedtest a few posts back)


June 19, 2006
In article <e752e2$27jq$1@digitaldaemon.com>, Jarrett Billingsley says...
>
>"Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:e752c0$27i8$1@digitaldaemon.com...
>
>> foreach(/* auto */ a; tiles)
>>    a[] = 0;
>
>This is why I hate newsgroups.
>
>foreach(inout /* auto */ a; tiles)
>    a[] = 0;
>
>

Having fun Jarrett :D

Thx I'll look through your propositions. (Ay, I only use static arrays)


June 19, 2006
On Mon, 19 Jun 2006 17:41:47 +0000 (UTC), MM <MM_member@pathlink.com> wrote:
> I did your insanity test.. And here there was no significant speed difference
> (also none with -O)

Thanks.

> But why do you use:
> arr = cast(TILE (*)[TILEW][TILEH])calloc(TILEW*TILEH,TILE.sizeof);
>
> Was that only for the size limit?

Yes. With TILEW && TILEH == 1000 the array would not fit on the stack, it gave a stack overflow error starting the program.

> I just used:
> TILE[TILEW][TILEH] arr;
>
> TILEW && TILEH == 250
>
> (Still the same speed)

I wanted to make the array big enough that stacking/copying it for each function call would be very noticable.

> Why this is the limit I don't understand, 16MB should be the limit, right?

I don't actually know what the stack limit it. For this test it doesn't really matter what the exact value is, the very fact that the program runs proves it's not stacking the entire array for each call to the function which is all I was trying to discover.

Thanks again for checking this for me.

Regan
June 19, 2006
I did a new test:

import std.c.stdlib;
import std.stdio;
import std.perf;

const int TILEW = 1000;
const int TILEH = 1000;

struct TILE { int x,y; int z[1]; }

void foo(TILE arr[TILEW][TILEH], int i) {
arr[i%TILEW][i%TILEH].x=i;
}

void main()
{
PerformanceCounter c = new PerformanceCounter();
int i;


TILE[TILEH][TILEW] arr2;
c.start();
for(i = 0; i < 10000000; i++) foo(arr2,i);
c.stop();
writefln("foo took: ",c.milliseconds());

}

It runs without a problem... I really don't know why and how, because just
yesterday it didn't :/
Is this maybe because some other program was using the same stack?
If this is true, how do I check how much is left on the stack?
I'm really not into this, I'm sorry.

The maximum size of an static array should be 16MB.
At least it says so here :)
http://www.digitalmars.com/d/arrays.html

Btw, is a stacked array a bad thing?


June 19, 2006
On Mon, 19 Jun 2006 23:14:01 +0000 (UTC), MM <MM_member@pathlink.com> wrote:
> I did a new test:
>
> import std.c.stdlib;
> import std.stdio;
> import std.perf;
>
> const int TILEW = 1000;
> const int TILEH = 1000;
>
> struct TILE { int x,y; int z[1]; }
>
> void foo(TILE arr[TILEW][TILEH], int i) {
> arr[i%TILEW][i%TILEH].x=i;
> }
>
> void main()
> {
> PerformanceCounter c = new PerformanceCounter();
> int i;
>
>
> TILE[TILEH][TILEW] arr2;
> c.start();
> for(i = 0; i < 10000000; i++) foo(arr2,i);
> c.stop();
> writefln("foo took: ",c.milliseconds());
>
> }
>
> It runs without a problem... I really don't know why and how, because just yesterday it didn't :/
> Is this maybe because some other program was using the same stack?

No. Each program gets it's own stack space. I believe it's possible to set the stack size on linux, not sure about windows. I am not sure what the default stack size is on either OS.

> If this is true, how do I check how much is left on the stack?

I'm not sure. I think you can obtain the address of the bottom or top of the stack and then measure the distance between that and the most recent stacked variable.. but you still need the total stack size, no idea really.

> I'm really not into this, I'm sorry.

It's not a problem at all. All I wanted was someone to check if my code was doing something silly :)

> The maximum size of an static array should be 16MB.
> At least it says so here :)
> http://www.digitalmars.com/d/arrays.html

I think this limit has something to do with the size of the data segment in an executable, as opposed to the stack size of a running process, though the two may be related.

> Btw, is a stacked array a bad thing?

I think that depends. Allocating memory on the stack is faster than on the heap, but if you're just allocating one huge block there should be no noticable difference (as it only occurs once). Stack memory is limited by the stack space, so why would you want to use it all up for no gain in speed? (or anything else). I think generally it's just a better idea to allocate large arrays on the heap using calloc or new or similar.

Regan
1 2
Next ›   Last »