simpledisplay.d now works on as 64 bit on X

Adam D. Ruppe destructionator at gmail.com
Sun Jun 9 06:22:14 PDT 2013


On Sunday, 9 June 2013 at 12:09:03 UTC, bearophile wrote:
> Time ago I tried simpledisplay (on 32 bit Windows) and I 
> remember I had to make the class Image final to have some 
> performance. I used it on Rosettacode too:

Hmm probably putPixel and impl.putPixel is too slow, it is called 
a lot. I made the class final now and got a about 8% improvement, 
using linux right now.

Eliminating those calls entirely, writing straight to the private 
rawData pointer, gives about 12% improvement, since this would 
get rid of calculating pixel offsets too (we can just do ptr++). 
Maybe I'll expose that and try to make it somehow cross platform.

I got as high as 45 fps using that trick plus the dmd -inline 
-release -O -noboundscheck flags. (The original code without 
flags and without final gave me only 30 fps).

I compiled and ran on wine too and it seems to have worked. 
Here's the nextState function using a pointer:


void nextState(ref World world, ref World nextWorld,
                ref Xorshift rnd, Image img) {
   auto pixelPointer = img.getDataPointer();
   auto linePadding = img.bytesPerLine() - img.bytesPerPixel * 
img.width;
   auto pixelPadding = img.bytesPerPixel() - 3;
   enum double div = cast(double)typeof(rnd.front()).max;
   immutable nr = world.length;
   immutable nc = world[0].length;
   foreach (r, row; world) {
     foreach (c, elem; row) {
       final switch (elem) {
         case Cell.empty:
		*pixelPointer++ = 255;
		*pixelPointer++ = 255;
		*pixelPointer++ = 255;
           //img.putPixel(c, r, white);
           nextWorld[r][c] = (rnd.front()/div)<P_PROB ? Cell.tree 
: Cell.empty;
           rnd.popFront();
           break;

         case Cell.tree:
           //img.putPixel(c, r, green);
	  	*pixelPointer++ = 0;
	  	*pixelPointer++ = 255;
	  	*pixelPointer++ = 0;

           foreach (rowShift; sp)
             foreach (colShift; sp)
               if ((r + rowShift) >= 0 && (r + rowShift) < nr &&
                   (c + colShift) >= 0 && (c + colShift) < nc &&
                   world[r + rowShift][c + colShift] == 
Cell.burning) {
                 nextWorld[r][c] = Cell.burning;
                 goto END;
               }

           nextWorld[r][c]=(rnd.front()/div)<F_PROB ? Cell.burning 
: Cell.tree;
           rnd.popFront();
           END: break;

         case Cell.burning:
           //img.putPixel(c, r, red);
	  	*pixelPointer++ = 0;
	  	*pixelPointer++ = 0;
	  	*pixelPointer++ = 255;
           nextWorld[r][c] = Cell.empty;
           break;
       }

       pixelPointer += pixelPadding;
     }

     pixelPointer += linePadding;
   }

   swap(world, nextWorld);
}


> I have tried that Forest fire code with your new version and it 
> gives me a:
> simpledisplay.d(676): Error: undefined identifier i, did you 
> mean variable s?

oops fixed. I added a new function but didn't even compile the 
Windows version of this change (only tried linux) and made a typo 
there.


More information about the Digitalmars-d-announce mailing list