Are compiler able to keep short[2] inside registers? I found horrible generated assembly while using shorts, so I guess it is worth the effort. However I would prefer real SWAR ...Bo Persson wrote:And how much do we now save, compared to actually storing two separate values of type short?mcostalba wrote:Ok, so what about this one ?Gian-Carlo Pascutto wrote: There is nothing in the C standard that guarantees that. See section 6.5.7, point 5:
http://www.open-std.org/JTC1/SC22/WG14/ ... /n1256.pdf
I have verified it works with all the compilers and does not rely on shifts or cast to shorts. I have found it googling around and it seems safe to me.Code: Select all
inline Value eg_value(Score s) { return Value((int)(unsigned(s) & 0x7fffu) - (int)(unsigned(s) & 0x8000u)); }
gcc miscompilation in Stockfish 1.6
Moderators: hgm, Rebel, chrisw
-
- Posts: 2250
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: gcc miscompilation in Stockfish 1.6
-
- Posts: 243
- Joined: Sat Mar 11, 2006 8:31 am
- Location: Malmö, Sweden
- Full name: Bo Persson
Re: gcc miscompilation in Stockfish 1.6
Looks good to me.Sven Schüle wrote:Exactly what I wanted to say, right in this minute. I think the whole issue has gone too far into bit twiddling "at its best" while not being necessary at all.Bo Persson wrote:And how much do we now save, compared to actually storing two separate values of type short?mcostalba wrote:Ok, so what about this one ?Gian-Carlo Pascutto wrote: There is nothing in the C standard that guarantees that. See section 6.5.7, point 5:
http://www.open-std.org/JTC1/SC22/WG14/ ... /n1256.pdf
I have verified it works with all the compilers and does not rely on shifts or cast to shorts. I have found it googling around and it seems safe to me.Code: Select all
inline Value eg_value(Score s) { return Value((int)(unsigned(s) & 0x7fffu) - (int)(unsigned(s) & 0x8000u)); }
I just renew my "class Score" proposal. This one compiles under GCC and includes everything you would really need. There is no bit operation involved, just two 16-bit values are kept and operated upon simultaneously. The user code needs a little bit of editing but I think it should be worth the small effort:Maybe someone comes up with something even better?Code: Select all
class Score { public: // constructors Score() : mg(0), eg(0) {} Score(int mg_val, int eg_val) : mg(mg_val), eg(eg_val) {} Score(int eg_val) : mg(0), eg(eg_val) {} // maybe subject of discussion // accessors int mg_value() const { return int(mg); } int eg_value() const { return int(eg); } // unary minus operator Score operator-() { return Score(-int(mg), -int(eg)); } // binary member operators Score operator+(Score s) { return Score(mg + s.mg, eg + s.eg); } Score operator-(Score s) { return Score(mg - s.mg, eg - s.eg); } Score operator+=(Score s) { mg += s.mg; eg += s.eg; return *this; } Score operator-=(Score s) { mg -= s.mg; eg -= s.eg; return *this; } // binary friend operators friend bool operator==(Score const & s1, Score const & s2) { return s1.mg == s2.mg && s1.eg == s2.eg; } friend bool operator!=(Score const & s1, Score const & s2) { return !(s1 == s2); } friend Score operator*(int i, Score s) { return Score(i * s.mg, i * s.eg); } friend Score operator*(Score s, int i) { return i * s; } // Division must be handled separately for each term friend Score operator/(Score s, int i) { return Score(s.mg / i, s.eg / i); } // Only declared but not defined. We don't want to multiply two scores due to // a very high risk of overflow. So user should explicitly convert to integer. friend Score operator*(Score s1, Score s2); private: int16_t mg; int16_t eg; };
Sven
Possibly you could make the constructor from int explicit, to avoid unwanted implicit conversions.
explicit Score(int eg_val) : mg(0), eg(eg_val) {}
-
- Posts: 243
- Joined: Sat Mar 11, 2006 8:31 am
- Location: Malmö, Sweden
- Full name: Bo Persson
Re: gcc miscompilation in Stockfish 1.6
I'm not sure about gcc, but I have seen that MSVC generates identical code (and actually shares the generated code) for these two vectors:Gerd Isenberg wrote:Are compiler able to keep short[2] inside registers? I found horrible generated assembly while using shorts, so I guess it is worth the effort. However I would prefer real SWAR ...Bo Persson wrote:And how much do we now save, compared to actually storing two separate values of type short?mcostalba wrote:Ok, so what about this one ?Gian-Carlo Pascutto wrote: There is nothing in the C standard that guarantees that. See section 6.5.7, point 5:
http://www.open-std.org/JTC1/SC22/WG14/ ... /n1256.pdf
I have verified it works with all the compilers and does not rely on shifts or cast to shorts. I have found it googling around and it seems safe to me.Code: Select all
inline Value eg_value(Score s) { return Value((int)(unsigned(s) & 0x7fffu) - (int)(unsigned(s) & 0x8000u)); }
Code: Select all
struct two_shorts
{
short x;
short y;
};
std::vector<int> v1;
std::vector<two_shorts> v2;
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: gcc miscompilation in Stockfish 1.6
yes, I would also think two int are better then two shorts. I think I will test this approach in the new SF development, but for the ready to be released 1.6.2 I would try to keep changes at a minimum also performance wise and re-testing performance of this for all the platforms is too much and is _not_ the correct timing IMHO. Now we should try to get out 1.6.2 with NO functionality changes and NO performance changes so that all the work done by the testers till now is not wasted.Bo Persson wrote: Looks good to me.
Possibly you could make the constructor from int explicit, to avoid unwanted conversions.
explicit Score(int eg_val) : mg(0), eg(eg_val) {}
Sven approach is very interesting but is new development cycle material IMHO, now I would go with what we already have in 1.6 + minimal fixes for making gcc -O3 compile to work.
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: gcc miscompilation in Stockfish 1.6
Perfectly fine for me, there is absolutely no reason to hurry at the wrong timemcostalba wrote:yes, I would also think two int are better then two shorts. I think I will test this approach in the new SF development, but for the ready to be released 1.6.2 I would try to keep changes at a minimum also performance wise and re-testing performance of this for all the platforms is too much and is _not_ the correct timing IMHO. Now we should try to get out 1.6.2 with NO functionality changes and NO performance changes so that all the work done by the testers till now is not wasted.Bo Persson wrote: Looks good to me.
Possibly you could make the constructor from int explicit, to avoid unwanted conversions.
explicit Score(int eg_val) : mg(0), eg(eg_val) {}
Sven approach is very interesting but is new development cycle material IMHO, now I would go with what we already have in 1.6 + minimal fixes for making gcc -O3 compile to work.
Sven
-
- Posts: 201
- Joined: Thu Mar 22, 2007 7:12 pm
- Location: Netherlands
Re: gcc miscompilation in Stockfish 1.6
In that case, Value variables can be have different sizes depending on the compiler (implementation defined).mcostalba wrote:It is defined just few lines above Score in value.h fileJan Brouwer wrote:How is Value exactly defined?
I didn't find in this thread (maybe I missed it).
Jan
Code: Select all
enum Value { VALUE_DRAW = 0, VALUE_KNOWN_WIN = 15000, VALUE_MATE = 30000, VALUE_INFINITE = 30001, VALUE_NONE = 30002 };
Interestingly, it seems that according C99, (unsigned) short is _not_ amongst the allowed sizes, but is allowed by the C++ standard.
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: gcc miscompilation in Stockfish 1.6
But this would involve passing around 8 bytes by value instead of 4 quite frequently.mcostalba wrote:yes, I would also think two int are better then two shorts.
"Trust your compiler"
Sven
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: gcc miscompilation in Stockfish 1.6
Anyhow in this case I would rule out Value to be implemented as short because you have data above 30000 to store, so it could be or int (and I would bet it is) or unsigned if the compiler wants to really hurt itself (and its users).Jan Brouwer wrote:In that case, Value variables can be have different sizes depending on the compiler (implementation defined).mcostalba wrote:It is defined just few lines above Score in value.h fileJan Brouwer wrote:How is Value exactly defined?
I didn't find in this thread (maybe I missed it).
Jan
Code: Select all
enum Value { VALUE_DRAW = 0, VALUE_KNOWN_WIN = 15000, VALUE_MATE = 30000, VALUE_INFINITE = 30001, VALUE_NONE = 30002 };
Interestingly, it seems that according C99, (unsigned) short is _not_ amongst the allowed sizes, but is allowed by the C++ standard.
If the compiler is really really evil it coudl try with unsigned short (because it's C++)...but I don't think compilers are so evil
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: gcc miscompilation in Stockfish 1.6
Yes I trust, but I also see that we have a lot of adds of the formSven Schüle wrote:But this would involve passing around 8 bytes by value instead of 4 quite frequently.mcostalba wrote:yes, I would also think two int are better then two shorts.
"Trust your compiler"
Sven
Code: Select all
eval += bonus; // both eval and bonus are Score