So I timed a short program with /Gd and /Gr

So I timed a short program with /Gd and /Gr

StopWatch timings
Image by Michal Jarmoluk from Pixabay

This was the follow up to yesterday’s post about seeing if changing the function calling convention, switching from stacked parameters to passing them in registers made a difference in execution time.

This was the program I used.

#include <stdio.h>
#include "hr_time.h"

int add(int a, int b, int c,int d,int e) {
	return a - b * 2 + c * 3 + d * 3 + e * 5;
}

int __cdecl main() {
	int total=0;
	stopWatch s;
	startTimer(&s);
	for (int i = 0; i < 10000000; i++) {
		total += add(i, 5, 6, i, 8);
	}
	stopTimer(&s);
	printf("Value = %d Time = %7f.5\n",total, getElapsedTime(&s));
}

Pretty similar to the one I did yesterday except with two more parameters in the add function and my Windows high-res timing code. I’ve extracted the two timing files (hr_time.h/.c) from the asteroids and it’s in the LearnC folder on GiHhub.

As before this was compiled as x86. Also I tried it first compiled as release. This means the optimizing compiler has its way and I got virtually identical for cdecl (/Gd), fastcall (/Gr) and even safecall (/Gz).

Disassembly of the machine code revealed that the optimizer had moved the function code inline in the for loop and this negated the call code. So I did it again in debug mode. Here there was a clear difference. The times for fastcall were 0.259 while the cdecl (the default) was 0.239 which is about an 8% speed increase. Safecall was roughly the same execution as cdecl. So the lesson seem to be don’t use fastcall.

I think I need a more complicated program which should be compiled in release mode but where optimization doesn’t transform the function into inline code. Perhaps making the function longer would do it so the function machine code would be too long to fit in a L1 cache.

Interestingly the release code execution time was 0.005557 seconds, almost 50 x faster than the debug time.

How much faster is C code compiled with fastcall?

How much faster is C code compiled with fastcall?

Setting fastcall in VS 2019Something I read about the other day was the __fastcall convention. In Visual Studio you enable this with the /Gr flag and in gcc (it’s __attribute__((fastcall)). For clang it’s fastcall but see this.

So what does fastcall do? It changes the calling convention, so instead of pushing parameters to a function on the stack, it passes them in the registers starting with ECX then EDX and so on.  Let’s look at an example.

#include <stdio.h>

int add(int a, int b, int c) {
	return a + b * 2 + c * 3;
}

int main() {
	printf("Add(4,5,6)=%d\n", add(4, 5, 6));
}

This is the disassembly code from VS 2019. I pressed F10 to start debugging then Debug => Windows => Disassembly to get the listing. Note thei is x86, ie 32-bit.

005B18DC  lea         edi,[ebp-0C0h]  
005B18E2  mov         ecx,30h  
005B18E7  mov         eax,0CCCCCCCCh  
005B18EC  rep stos    dword ptr es:[edi]  
005B18EE  mov         ecx,offset _9831A1D6_test@c (05BC003h)  
005B18F3  call        @__CheckForDebuggerJustMyCode@4 (05B131Bh)  
	printf("Add(4,5,6)=%d\n", add(4, 5, 6));
005B18F8  push        6  
005B18FA  push        5  
005B18FC  push        4  
005B18FE  call        _add (05B1023h)  
005B1903  add         esp,0Ch  
005B1906  push        eax  
005B1907  push        offset string "Add(4,5,6)=%d\n" (05B7B30h)  
005B190C  call        _printf (05B10D2h)  

Now if I build it after setting the /Gr flag. In Vs 2019, on the project property pages, click advanced then the Calling Convention and switch from cdecl (/Gd) to –fastcall (/Gr).

008118EC  lea         edi,[ebp-0C0h]  
008118F2  mov         ecx,30h  
008118F7  mov         eax,0CCCCCCCCh  
008118FC  rep stos    dword ptr es:[edi]  
008118FE  mov         ecx,offset _9831A1D6_test@c (081C003h)  
00811903  call        @__CheckForDebuggerJustMyCode@4 (081131Bh)  
	printf("Add(4,5,6)=%d\n", add(4, 5, 6));
00811908  push        6  
0081190A  mov         edx,5  
0081190F  mov         ecx,4  
00811914  call        @add@12 (0811276h)  
00811919  push        eax  
0081191A  push        offset string "Add(4,5,6)=%d\n" (0817B30h)  
0081191F  call        _printf (08110CDh) 

I’ve highlighted the differences in bold. However the function Add is also different as the fastcall version doesn’t have to pop parameters off the stack.

Note, to get this to compile I had to prefix main with __cdecl. Using /Gr means that every function in the program uses registers and that’s not allowed with main as it’s called from Windows end must use the cdecl (default stack passing) convention.

This is what main looks like now.

int __cdecl main() {

Notes

This is only for 32-bit. 64-bit code is done somewhat differently so possibly wouldn’t be that different. Next I have to write a program that does lots of function calls and use high precision timing to see how much of a difference it makes. To be continued.

C Tutorial thirteen published on allocating memory

C Tutorial thirteen published on allocating memory

Memory chips
Image by PublicDomainPictures from Pixabay

I’ve restricted this tutorial to using malloc as it’s the main way you allocate and use dynamic memory in the thirteenth tutorial.

Pointers hold an address (of somewhere in RAM) and this can be an existing variable, a function or even data like a text string. But if you want to reserve a block of RAM and get a pointer to it, you have to call the stdlib function malloc(). (Or calloc, but I will return to that in a future tutorial).

Of course once you’ve finished using a block of RAM, it’s only polite to return it to the operating system by calling free(). Don’t forget either that malloc always returns a void * pointer, so you should cast it to something appropriate.

 

C Tutorial twelve on function pointers published

C Tutorial twelve on function pointers published

Lots of pointers
Image by pencil parker from Pixabay

While function pointers are important. I don’t think they’re quite as important as pointers. C would just not be C without pointers. There are so many things that you would not be able to do if the language lacked pointers. Things like most data structures (try doing a linked list without pointers!) .

However function pointers give additional flexibility. You can pass them as parameters in functions and store them in variables.

These are the earlier tutorials on pointers:

And this is the new one:

 

Santa Paravia en Fiumaccio

Santa Paravia en Fiumaccio

Santa Paravia en FiumaccioI could understand you thinking “have I flipped my lid?”. What kind of a title is “Santa Paravia en Fiumaccio”? It’s actually the name of an old game written in C. A much more sophisticated Hammurabi if that makes sense.  You can read about it here on Wikipedia.

I was digging around the web looking for games in C with source code and came across a reference to it. I found it on archive.org though that version is a bit bashed up, All the < and > are displayed as their HTML equivalents – &lt; and &gt; so you need to do copy and replace on that. Plus a few of them have spaces between the & and the lt/gt!

That was about a thousand lines long. However I thought, why not do a search on the web specifically for it and found a cleaned up and slightly longer version on GitHub by DNSGeek. If you dig into his repository list you’ll see he’s also done a Python port with graphics! It also includes the instructions for playing it in a PDF.

If you try and compile the C source code, you’ll find that a curses library is missing. I’m not sure that it actually needs it so I commented out the include line and it didn’t seem to mind.  Under Visual Studio, it complains because of the strcpy functions that should be strcpy_s.

So I’ll fix the little things and see how ityplays. You just have to love a game that has functions with names like SerfsDecomposing() and SerfsProcreating()!

 

Other simple game ideas

Other simple game ideas

Dice
Image by Ana Carolina Franco from Pixabay

My recent blog about the L-Game reminded me of other simple games and I did a bit of digging on the web.  If you are ever looking for ideas for games or game mechanics, take a look at the Wikipedia page on abstract strategy games.

It reminds me of my teenage years when I used to get Games & Puzzles magazine. Here’s an interesting list of subjects from there, many with links.  I wrote my first game for my O-Level (you were allowed to do games in those days) based on  game I saw in Games & Puzzles magazine.  It was a tennis game using 2 dice. Here’s the game play details.

The tennis court is split into 12 segments numbered 1-12 with the net between segments 6 and 7. Bit Like this:

   Opponent
-----------
12        1
11        2
10        3
9         4
8         5
7         6
--- Net ----
6         7
5         8
4         9
3        10
2        11
1        12
-----------
   You

The ball starts with you. To serve, you roll two dice and move the ball by the total. So if you get less than 7 then the serve failed as the ball doesn’t cross the net, otherwise it moves the ball by that amount so it ends in segments 7-12.

If for example you rolled 9 then the ball would be in segment 9 which from your opponents point of view is 4. The opponent can now roll either one or two dice and move the ball by the amount. In this case I’d choose one dice as a roll of 1 or 2 would fall short but 3-6 would get it over the net. If you rolled two dice then 9 or above would take the ball out of the court.  There’s no real skill except figuring out whether 1 or 2 dice maximises the odds of the ball staying in play.

It’s a fun little game and easy to code in C or any language.

BBC Basic with SDL

BBC Basic with SDL

BBC Micro
From Wikipedia

Back in my games programming days I never had a BBC  micro, though I knew several people who did including one bloke who let people run their ROMs on his micro. Sneakily it made a copy of the ROM contents and saved it to disk. I remember wasting a lot of hours playing Elite on a Beeb back in 1984.

BBC BASIC for SDL 2.0 is a cross-platform implementation of the BBC BASIC programming language for Windows, Linux (x86), MacOS, Raspbian (Raspberry Pi), Android, iOS and Emscripten / WebAssembly by developer R.T. Russell. If you ever fancied writing BASIC programs and running them on a BBC Micro then you now can with this.

It is programmed in C (and I’ve added a link into the C code library) and you’ll find the multi-platform source on GitHub. A visit to the Complete BBC Games archive might also be in order!

 

An intriguing Matchbox based learning machine

An intriguing Matchbox based learning machine

Matchbox
Image by Horst Winkler from Pixabay

I mentioned Menace the other day. This was a “Learning Machine” implemented entirely with Matchboxes. This was back in the 1960s. The idea is that a simple game like noughts and crosses (aka Tic-tac-toe) can be played by a crude form of learning computer.

You need enough matchboxes for every possible position in the game. That’s 304 matchboxes and you start but putting four coloured beads into each box for every possible turn. These represent the possible moves. To make a move, you pick the box corresponding to the position shake it and draw a bead out and play that move.

And so on until the game is finished. Then if Menace (as it was called- Machine Educable Noughts And Crosses Engine) won, you add three beads to each winning Matchbox, put one back in if its a draw and remove all of that colour if it lost.  Gradually it becomes better at winning.

There’s a far detailed write up here. It’s an intriguing technique though possibly not the easiest to apply as it requires you to have a matchbox for every position in a game. Fine with noughts and crosses but impossible with chess. Instead of Matchboxes, it could be done way faster in software.

It needs games with determinate moves and not too many, though I suppose with RAM in modern PCs, a few million moves would be manageable. One possibility would be the L game. I’ve never heard of anyone doing that, and it would make for an interesting project. I’ll add it to my list of future projects. Now I wonder how many possible moves there are in a L- Game? It’s made more complex because you can optionally move one of the single pieces as well as the L-Shape which can be rotated and flipped and it’s a 4 x 4 board not 3 x 3 as in noughts and crosses. .

Thinking about Slay tutorial 7- Game AI

Thinking about Slay tutorial 7- Game AI

Slay gamesHaving just published Slay Tutorial three, making the Onslaught game play well as a computer opponent(well up to 8 of them)  has been weighing on my mind. I have played the original Slay perhaps a couple of thousand times, so I’m reasonably familiar with strategy.

There’s almost 500 games on the Slay game chooser screen shown with four different sizes of islands; the four boxes. Usually by the time I’ve played through all games here (probably taking 18 months to two years) , I can start again and have forgotten what it was like. Plus I think it randomises the starting positions so you get a lot of replay value.

In the first Slay Tutorial I published a map of the tutorials and so far am sticking to it. Tutorial seven is the one for the game AI and its on my mind. I play all the Slay games at the same top intelligence level and even it sometimes makes stupid mistakes like leaving an area vulnerable to splitting and losing all units due to starvation.

The main aim of any player is to expand their territory at the expense of other players. Joining territories can be one tactic as its lets you support the bigger units. The 2 point unit is a Peasant then there’s Spearmen (6 points) , Knights (18 point) and Baron (54 points).  Getting a Knight early on gives you a big advantage as it can defeat castles and too often I’ve seen a territory with one or two spearmen get trapped by castles and destroyed in a few turns.

Likewise putting a castle down early on can secure a territory for a while. Or if you have a larger area, a couple of castles can shield your flanks so you can focus yoyr troops against one enemy and not worry about other players moving in.

Self Playing

In Slay once you are eliminated the games plays through until one player beats everyone else. But self-playing can also be a useful way to have computer players learn. One possibility is to try and implement a “matchbox” AI. This was done with Tic-Tac-Toe (noughts and crosses for us Brits) with Menace, Now it may be that Onslaught is too complex to implement that but there’s a lot of RAM available, so if I can limit the number of setups that it recognises then maybe?

Anyway there’s a fair bit of time and Tutorials 4-6 to do before I get to Tutorial seven.

PS

If you move the mouse over the About Me, you’ll see a link to a page that has short cut links to all blog posts along with the title of each.  It’s a quicker way of navigating.

 

Thinking about my Inselkampf reimagination

Thinking about my Inselkampf reimagination

Database schema
Image by mcmurryjulie from Pixabay

In an earlier post on web games, I mentioned an old multi-player web game that I used to play and which was discontinued in 2014.  I have a rough design for this and am busy learning Blazor as I believe that would be the best technology to use. It lets you run C# programs in the browser, no JavaScript needed. This simplifies input with verification and also updating the web page without having to do lots of messy Ajax stuff.

But being a web game there is a web server involved and the big question is what sort of data architecture to use? The most obvious one is probably using a relational database behind the scenes. That way each game (with up to 1,000 players) is held in a single database in about 12 tables. I’ll probably use MariaDB.

I did consider doing everything in RAM but its a terrible abuse of a web server and rather restricts it to running one or two games. Pulling stuff out of a database is much less strain on the system than having a few hundred MB of RAM tied up per game. A web server can support multiple games which helps keep the costs down.

Also with a web game, it raises the possibility of caching certain static files on disk to improve throughput.  This blog uses WordPress but has a cache so when you view a page, it’s almost certainly been pre-generated rather than built on the fly.

An example of a web game that I admire is Torn.com.