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) ));
#endif
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:
Code: Select all
#ifdef __clang__
typedef int eval_t __attribute__ (( ext_vector_type(2) ));
#else
typedef int eval_t __attribute__ (( vector_size(8) ));
#endif
What solution would did you choose for your engine ?
What would you choose, in hindsight ?