Moderator: Andres Valverde
Sven Sch?le wrote:I hope my interpretation of Fabien's code is right, of course I might have missed some important detail.
Uri Blass wrote:I see in move_do.cpp
- Code: Select all
ASSERT(board->number[piece_12]<9);
board->number[piece_12]++;
I think that it is wrong because there may be 10 rooks or 10 knights or 10 bishops in chess.
int max_number[] = { 8, 8, 10, 10, 10, 10, 10, 10, 9, 9, 1, 1 };
...
ASSERT(board->number[piece_12] < max_number[piece_12]);
Sven Sch?le wrote:Uri Blass wrote:I see in move_do.cpp
- Code: Select all
ASSERT(board->number[piece_12]<9);
board->number[piece_12]++;
I think that it is wrong because there may be 10 rooks or 10 knights or 10 bishops in chess.
The ASSERT seems to wrong, should perhaps be something like this:
- Code: Select all
int max_number[] = { 8, 8, 10, 10, 10, 10, 10, 10, 9, 9, 1, 1 };
...
ASSERT(board->number[piece_12] < max_number[piece_12]);
Sven
Dann Corbit wrote:Sven Sch?le wrote:Uri Blass wrote:I see in move_do.cpp
- Code: Select all
ASSERT(board->number[piece_12]<9);
board->number[piece_12]++;
I think that it is wrong because there may be 10 rooks or 10 knights or 10 bishops in chess.
The ASSERT seems to wrong, should perhaps be something like this:
- Code: Select all
int max_number[] = { 8, 8, 10, 10, 10, 10, 10, 10, 9, 9, 1, 1 };
...
ASSERT(board->number[piece_12] < max_number[piece_12]);
Sven
I think it is an array bounds check.
If the index is 8 or less then you can increment it.
If the index is 9, when incremented it will become 10.
That would indicate 11 chessmen and is too large.
So I think that the assert is correct.
The suggestion to use an array to check for smaller bounds for a given type is a good one, but Fabien is checking pre-increment and the numbers provided are post-increment. Also, it is a big mistake to ever increment (or decrement) the king count.
IMO-YMMV.
Dann Corbit wrote:If the index is 9, when incremented it will become 10.
That would indicate 11 chessmen and is too large.
Dann Corbit wrote:The suggestion to use an array to check for smaller bounds for a given type is a good one, but Fabien is checking pre-increment and the numbers provided are post-increment.
Dann Corbit wrote:Also, it is a big mistake to ever increment (or decrement) the king count.
Dann Corbit wrote:int foo[10];
int index = 10;
foo[index] = 5; /* This overwrites memory because 10 is too large. */
LOCALITY OF REFERENCE
The FOREMOST consideration when optimizing memory access, whether for virtual memory or cache considerations, is locality of reference. That is the property of a program to use addresses which are near (in both time and location) other recent references to memory. The main difference between optimizing for VM and optimizing for cache is scale: VM pages can be anywhere from 0.5kb to 8kb and beyond and can take tens of milliseconds to read in from disk. Cache blocks typically range from 16 bytes to 256 bytes and get read in in the tens of microseconds. A program which forces many VM pages or cache lines to load in quick succession is said to be "thrashing."
You can affect locality of reference by changing the order in which you access and allocate things and by splitting your data structures into "frequently used" and "infrequently used" segments and allocating all the "frequently used" stuff together. (But don't fool yourself into thinking that malloc always allocates adjacent chunks of memory on each successive call. You have to allocate one giant chunk and dole it out yourself to be certain. But this can lead to other problems.)
Chan Rasjid wrote:{snip}
1) I had silly things like int fn(char a, char b);
2) Gian mentioned not to pass pointers(to var ?) as function parameters
but did not expained fully. Consider:-
int AA, b, c;
//at this point optimization may want AA in register
b = fn(&AA);
with the fn() call, AA must be pushed back to stack as ®ister is invalid.
Of course it becomes an issue only if the codes are critically active.
So the rule is only to pass only int(never char/short) or pointer to struct as function arguments.
{snip}
Rasjid
Dann Corbit wrote:Chan Rasjid wrote:{snip}
1) I had silly things like int fn(char a, char b);
2) Gian mentioned not to pass pointers(to var ?) as function parameters
but did not expained fully. Consider:-
int AA, b, c;
//at this point optimization may want AA in register
b = fn(&AA);
with the fn() call, AA must be pushed back to stack as ®ister is invalid.
Of course it becomes an issue only if the codes are critically active.
So the rule is only to pass only int(never char/short) or pointer to struct as function arguments.
{snip}
Rasjid
That rule is simply wrong. If you pass a struct by value instead of by pointer or by reference, then it will push a copy of the entire structure onto the stack. That is so bad that it deserves no further mention. The only time you should pass a struct by value is if it must not be changed, and even then you could pass pointer to const or rerference to const which would be much better.
As far as passing objects on a stack instead of pointers to objects -- in the first place, you are only pushing at most sizeof(address) when you pass a pointer. On a 32 bit system (or a 64 bit system with 32 bit addressing) you are pushing one 4 byte value. The cost for that is very small.
Now, passing by register is faster than passing by value for a calling convention. But we are talking about 1% or 2% at most for a program speed to improve by this change.
Those rules are silly rules and wrong rules. By far, far, far write code that is clear and expresses your meaning in the best way. Any savings you might hope for from passing a value verses passing an address are going to be marginal or even negative.
Don't do that. I do not see places in Fabien's code where he abuses those sorts of rules. I think it is imagination.
diepeveen wrote:Dann,
If you can save 1% somewhere with just a week work, you must do it. I would never ignore a hint of GCP in that respect.
Good programmers don't only write the right code, they also optimize it utmost.
Vincent
mridul wrote:There is a difference between writing a program from scratch and a program which has already matured and optimised.
When progress becomes tougher , when you have eliminated all bugs you can find and cant find any new ones , when adding a new "feature" becomes more expensive than the benifits ... you can keep expirimenting with new ideas , but anything which gives you 1% improvement will be very carefully pursued.
This is common not just to chess but to most other s/w & h/w projects.
And dont take anything and everything stated in context of Fruit and Fabien.
Uri Blass wrote:{snip}
My division of the code to files is not good and I think that how to divide code to files is the first thing that I can learn from fruit(I may work slightly more about movei of today because I started to work on a function to generate only checks and did not finish it but basically I plan to start a new project when I may copy and paste part from the old project but the organization of files will be different) .
Uri
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 40 guests