Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2001:
[Freeciv-Dev] Re: Profiling Civserver again
Home

[Freeciv-Dev] Re: Profiling Civserver again

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Gregory Berkolaiko <Gregory.Berkolaiko@xxxxxxxxxxxxxx>
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: Profiling Civserver again
From: "Ross W. Wetmore" <rwetmore@xxxxxxxxxxxx>
Date: Wed, 01 Aug 2001 11:19:01 -0400

At 05:21 AM 01/08/01 +0300, Gregory Berkolaiko wrote:
>
>Jason is right when he says that cleaning up map_adjust_x should do good.
>I think a good portion of CPU time spent in get_map_tile is wasted on two
>modulus ( % ) operations in map_adjust_x.  One is completely unnecessary,
>as was mentioned earlier.  Is it possible to get rid of the second one(s)
>in a safe way without converting the macro to a function?
>
>Err, and a stupid question, how does int -> unsigned int conversion work?
>Is the behaviour standard?

I don't know of any remaining hardware that doesn't use 2s complement
integer representations, and I think the standard for integer conversions
has been established for 20 years or so that conversion operations like
char to unsigned long first sign extend the word size to long then treat
it as unsigned.

Thus negative numbers are always really big positive numbers in an unsigned
compare operation, or to put it another way, unsigned numbers wrap from 0
to the largest positive if you decrement by 1, whereas 0 goes to -1 and the
smallest negative number wraps to the largest positive one in a signed
interpretation of the bits. The trick is to make sure the compiler uses 
unsigned hardware compares instead of signed compares.

It is somewhat sleazy from an aesthetic standpoint, but the sort of thing 
one does in extreme cases where the optimization warrants it :-).

And, no it is not stupid. I don't think most people get exposed to hardware
or really low level details anymore to the extent that happened a number of
years back when this was both required and there wasn't as much stuff in
between to learn as there is now :-).

If you do the same trick with map_adjust_x, you can test for the border
cases in one operation and avoid redundant "%"s. If you assume map.xsize
is always positive (would be an interesting game if it weren't), then you
can avoid one "%". If you assume the only valid range for out-of-bounds
is one map.xsize above or below, then you can drop the "%"s. But with the
added border check, I would not worry about the expense of saving 2 % vs
adding one "-" on 100 border ops in a 4000 map, since the % is actually 
safer.

#define map_adjust_x(X)                        \
  ((unsigned)(X) < (unsigned)map.xsize ? (X)   \
  : ((X) < 0 ? (X) % map.xsize + map.xsize : (X) % map.xsize))

Cheers,
RossW

>G.
>
>On Tue, 31 Jul 2001, Ross W. Wetmore wrote:
>
>> Personally I prefer doing something like the following in map.h ...
>> 
>> #ifndef MAP_GET_TILE_FUNCTION
>> 
>> /* WARNING: these are macros - do not use arguments with side effects */
>> #define map_get_tile(x,y)    ( \
>>   ((unsigned)(y) >= (unsigned)map.ysize)  \
>>   ? &void_tile               \
>>   : map_get_tile_unchecked(map_adjust_x(x),(y)))




[Prev in Thread] Current Thread [Next in Thread]