eval type
Posted: Sat Jun 20, 2015 2:43 am
I'm wondering how to best choose the type of eval(opening, endgame). There are quite a few solutions:
1/ two ints (eg. Fruit)
Advantage: straight forward.
Disadvantage: No vectorized syntax. Lots of repetitive code to deal with op and eg at the same time.
2/ single int (eg. SF)
Advantage: vectorized syntax.
Disadvantage: still need to implement some operators manually (division doesn't work and needs to be done component by component for example). Also, it's a can of worms of portability issues and signed overflow problems, so it's easy to have subtle bugs with this.
3/ portable C++
Package two int in some structure and define operators. Either of:
Advantage: vectorized syntax
Disadvantage: you need to define tons of operators (+move semantic).
4/ built-in vector syntax
Advantage: Vectorized syntax. Performance. No need to define any operator manually.
Disadvantage: To get best performane (using SIMD), you need to make it 128 bit long instead of 64. That's twice more memory that you want (if you story many of those in memory, can increase cache pressure). Doesn't port beyond GCC and Clang.
Regarding 4/, I am wondering what happens with 64-bit only:
Any chance the compiler can do something smart with that ? Or would it have to resort to software emulation equivalent to solution 3/ ?
What solution would did you choose for your engine ?
What would you choose, in hindsight ?
1/ two ints (eg. Fruit)
Code: Select all
int op, eg;Disadvantage: No vectorized syntax. Lots of repetitive code to deal with op and eg at the same time.
2/ single int (eg. SF)
Code: Select all
int eval;Disadvantage: still need to implement some operators manually (division doesn't work and needs to be done component by component for example). Also, it's a can of worms of portability issues and signed overflow problems, so it's easy to have subtle bugs with this.
3/ portable C++
Package two int in some structure and define operators. Either of:
Code: Select all
typedef int[2] eval_t;
typedef std::array<int, 2> eval_t;
struct eval_t { int op, eg; };
std::pair<int, int>;
Disadvantage: you need to define tons of operators (+move semantic).
4/ built-in vector syntax
Code: Select all
#ifdef __clang__
typedef int64_t eval_t __attribute__ (( ext_vector_type(2) ));
#else // assume GCC
typedef int64_t eval_t __attribute__ (( vector_size(16) ));
#endifDisadvantage: To get best performane (using SIMD), you need to make it 128 bit long instead of 64. That's twice more memory that you want (if you story many of those in memory, can increase cache pressure). Doesn't port beyond GCC and Clang.
Regarding 4/, I am wondering what happens with 64-bit only:
Code: Select all
#ifdef __clang__
typedef int eval_t __attribute__ (( ext_vector_type(2) ));
#else
typedef int eval_t __attribute__ (( vector_size(8) ));
#endifWhat solution would did you choose for your engine ?
What would you choose, in hindsight ?