Blit1to2 optimization

hello all,
I’m working on the porting of a game to a 16 bit/pixel embedded Linux box.
This game is 8 bit/pixel and I noticed a lot of performance loss in the 8 to 16
bit/pixel conversion function of a SDL_Surface: Blit1to2
I tried a modified version of Blit1to2 that uses a palette lookup table of 2
entries built in this way:

lookup_map[65536];
Uint16 cc = 0;
while (1) {
lookup_map[cc] = map[cc & 0x000000FF] | (map[(cc & 0x0000FF00) >> 8] << 16);
if (++cc == 0) break;
}

then, instead of working on every single source byte, as the original code do:
*(Uint16 *)dst = map[*src++];

I work on a couple of bytes:
*(int )dst = lookup_map[(Uint16 *)src];

I tried this version on my game and I had about five more frames (28 -> 32).
Valgring tells me the new version is about two time faster, compared to the
previous one. Obviously it requires 64K more space (for every palette table, but
in my case I’ve only one of it) and the cache miss will increase (the new table
is a lot bigger than the old one).
Nethertheless, I gained 5 frames on a Geode processor, that has a very small
cache.

Do you thing it can be worth one’s while to create a patch and submit it to this
newsgroup? I ask this question because a lot of work must be done in order to
transform my test code in a real patch :slight_smile:

Gianni

It’d be if extra mem eaten is good or not. I know on my PDA, I’d be annoyed
at sizeof(int) * 64K being eaten up :slight_smile: (given that lookup_map isn’t typed,
it’d default to an int).

Generally, what you should probably do is convert your surface to the native
screen type. This way it doesn’t have to convert on every blit.

-WillOn 12/27/06, Gianni Trevisti <g.trevisti at gmail.com> wrote:

hello all,
I’m working on the porting of a game to a 16 bit/pixel embedded Linux box.
This game is 8 bit/pixel and I noticed a lot of performance loss in the 8
to 16
bit/pixel conversion function of a SDL_Surface: Blit1to2
I tried a modified version of Blit1to2 that uses a palette lookup table of
2
entries built in this way:

lookup_map[65536];
Uint16 cc = 0;
while (1) {
lookup_map[cc] = map[cc & 0x000000FF] | (map[(cc & 0x0000FF00) >> 8]
<< 16);
if (++cc == 0) break;
}

then, instead of working on every single source byte, as the original code
do:
*(Uint16 *)dst = map[*src++];

I work on a couple of bytes:
*(int )dst = lookup_map[(Uint16 *)src];

I tried this version on my game and I had about five more frames (28 ->
32).
Valgring tells me the new version is about two time faster, compared to
the
previous one. Obviously it requires 64K more space (for every palette
table, but
in my case I’ve only one of it) and the cache miss will increase (the new
table
is a lot bigger than the old one).
Nethertheless, I gained 5 frames on a Geode processor, that has a very
small
cache.

Do you thing it can be worth one’s while to create a patch and submit it
to this
newsgroup? I ask this question because a lot of work must be done in order
to
transform my test code in a real patch :slight_smile:

Gianni


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

It’d be if extra mem eaten is good or not. I know on my PDA, I’d be annoyed
at sizeof(int) * 64K being eaten up :slight_smile: (given that lookup_map isn’t typed, it’d
default to an int).Generally, what you should probably do is convert your
surface to the native screen type. This way it doesn’t have to convert on every
blit.
-Will

Hello,

for sure it’s better to work using the native screen type. Unfortunately the
game I’m working on comes from Amiga, and there is a lot of code written with 8
bit/pixel in mind, so it is an hard work :slight_smile:

On a PDA (at least one of the current generation) you’re right.
But on a Set Top Box or an old PC (a machine with some mega of memory, I mean)
it can be useful. Consider that the current version perform 105% more read to
instruction code and 100% more to data (stat coming from cachegrind).
So if you’ve to perform this operation a lot of times and you’ve 256 KB of spare
memory, isn’t good to save so much CPU?

Gianni