test x86_64 extensions performance #14

Open
opened 2024-05-21 10:53:27 +02:00 by bruno · 1 comment
Owner
For example: - ~~fast pawn capture mask: https://www.chessprogramming.org/XOP#Applications~~ - fast HQ: https://www.chessprogramming.org/SSSE3
Author
Owner

XOP was abandoned, forget about it. However, I started to make some tests before understanding this is a dead-end:

#include <stdio.h>
#include <stdalign.h>
#include <x86intrin.h>

typedef enum {
    NORTH = 8,
    EAST =  1,
    SOUTH = -NORTH,
    WEST = -EAST,

    NORTH_EAST = (NORTH + EAST),
    SOUTH_EAST = (SOUTH + EAST),
    SOUTH_WEST = (SOUTH + WEST),
    NORTH_WEST = (NORTH + WEST),
} dir_t;

typedef unsigned long u64;
typedef u64 bitboard_t;

#define FILE_Abb 0x0101010101010101ull
#define FILE_Hbb 0x8080808080808080ull
typedef enum { WHITE, BLACK } color_t;

#include <stddef.h>

static __inline bitboard_t shift_ne(const bitboard_t bb)
{
    return (bb & ~FILE_Hbb) << NORTH_EAST;
}
static __inline bitboard_t shift_se(const bitboard_t bb)
{
    return (bb & ~FILE_Hbb) >> -SOUTH_EAST;
}
static __inline bitboard_t shift_sw(const bitboard_t bb)
{
    return (bb & ~FILE_Abb) >> -SOUTH_WEST;
}
static __inline bitboard_t shift_nw(const bitboard_t bb)
{
    return (bb & ~FILE_Abb) << NORTH_WEST;
}

#define pawn_shift_upleft(bb, c)  ((c) == WHITE ? shift_nw(bb): shift_se(bb))
#define pawn_shift_upright(bb, c) ((c) == WHITE ? shift_ne(bb): shift_sw(bb))

#define pawn_attacks_bb(bb, c)    (pawn_shift_upleft(bb, c) |                   \
                                   pawn_shift_upright(bb, c))

u64 pawn_capture(u64 opp, u64 pawns, color_t c)
{
    return opp & pawn_attacks_bb(pawns, c);
}

__m128i  noEa_noWe_Attacks(__m128i wPawns)
{
   const __m128i shifts = _mm_set_epi64x(0x0101010101010101, 0xFFFFFFFFFFFFFFFF); /* +1,... , -1,... */
   __m128i b;
   b = _mm_shl_epi8(wPawns, shifts); /* east:west */
   b = _mm_slli_epi64 (b, 8); /* north */
   return b;
}
__m128i  soEa_soWe_Attacks(__m128i wPawns)
{
   const __m128i shifts = _mm_set_epi64x(0x0101010101010101, 0xFFFFFFFFFFFFFFFF); /* +1,... , -1,... */
   __m128i b;
   b = _mm_shl_epi8(wPawns, shifts); /* east:west */
   b = _mm_srli_epi64 (b, 8); /* south */
   return b;
}

u64 capt2(u64 opp, u64 pawns, color_t c)
{
    alignas(16) unsigned long long ret[2];
    __m128i retx;
    __m128i pawnsx = _mm_set_epi64x(pawns, pawns);
    retx = c == WHITE?
    noEa_noWe_Attacks(pawnsx):
     soEa_soWe_Attacks(pawnsx);
    _mm_store_si128((__m128i*)ret, retx);
    return opp & (ret[0] | ret[1]);
}


main(ac, av)
{
    u64 p = 0x00ff00ffff00ff00;
    u64 opp = 0xffffffffffffffff;

    printf("1w=%lx\n", pawn_capture(opp, p, WHITE));
    printf("1b=%lx\n", pawn_capture(opp, p, BLACK));
    printf("2w=%lx\n", capt2(opp, p, WHITE));
    printf("2b=%lx\n", capt2(opp, p, BLACK));
}
XOP was abandoned, forget about it. However, I started to make some tests before understanding this is a dead-end: ``` C #include <stdio.h> #include <stdalign.h> #include <x86intrin.h> typedef enum { NORTH = 8, EAST = 1, SOUTH = -NORTH, WEST = -EAST, NORTH_EAST = (NORTH + EAST), SOUTH_EAST = (SOUTH + EAST), SOUTH_WEST = (SOUTH + WEST), NORTH_WEST = (NORTH + WEST), } dir_t; typedef unsigned long u64; typedef u64 bitboard_t; #define FILE_Abb 0x0101010101010101ull #define FILE_Hbb 0x8080808080808080ull typedef enum { WHITE, BLACK } color_t; #include <stddef.h> static __inline bitboard_t shift_ne(const bitboard_t bb) { return (bb & ~FILE_Hbb) << NORTH_EAST; } static __inline bitboard_t shift_se(const bitboard_t bb) { return (bb & ~FILE_Hbb) >> -SOUTH_EAST; } static __inline bitboard_t shift_sw(const bitboard_t bb) { return (bb & ~FILE_Abb) >> -SOUTH_WEST; } static __inline bitboard_t shift_nw(const bitboard_t bb) { return (bb & ~FILE_Abb) << NORTH_WEST; } #define pawn_shift_upleft(bb, c) ((c) == WHITE ? shift_nw(bb): shift_se(bb)) #define pawn_shift_upright(bb, c) ((c) == WHITE ? shift_ne(bb): shift_sw(bb)) #define pawn_attacks_bb(bb, c) (pawn_shift_upleft(bb, c) | \ pawn_shift_upright(bb, c)) u64 pawn_capture(u64 opp, u64 pawns, color_t c) { return opp & pawn_attacks_bb(pawns, c); } __m128i noEa_noWe_Attacks(__m128i wPawns) { const __m128i shifts = _mm_set_epi64x(0x0101010101010101, 0xFFFFFFFFFFFFFFFF); /* +1,... , -1,... */ __m128i b; b = _mm_shl_epi8(wPawns, shifts); /* east:west */ b = _mm_slli_epi64 (b, 8); /* north */ return b; } __m128i soEa_soWe_Attacks(__m128i wPawns) { const __m128i shifts = _mm_set_epi64x(0x0101010101010101, 0xFFFFFFFFFFFFFFFF); /* +1,... , -1,... */ __m128i b; b = _mm_shl_epi8(wPawns, shifts); /* east:west */ b = _mm_srli_epi64 (b, 8); /* south */ return b; } u64 capt2(u64 opp, u64 pawns, color_t c) { alignas(16) unsigned long long ret[2]; __m128i retx; __m128i pawnsx = _mm_set_epi64x(pawns, pawns); retx = c == WHITE? noEa_noWe_Attacks(pawnsx): soEa_soWe_Attacks(pawnsx); _mm_store_si128((__m128i*)ret, retx); return opp & (ret[0] | ret[1]); } main(ac, av) { u64 p = 0x00ff00ffff00ff00; u64 opp = 0xffffffffffffffff; printf("1w=%lx\n", pawn_capture(opp, p, WHITE)); printf("1b=%lx\n", pawn_capture(opp, p, BLACK)); printf("2w=%lx\n", capt2(opp, p, WHITE)); printf("2b=%lx\n", capt2(opp, p, BLACK)); } ```
bruno added the
enhancement
label 2024-05-22 20:30:24 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bruno/brchess#14
No description provided.