zullil wrote:No need for the snarky "thanks for wasting our time" either.
Well, you said you were "summarizing", not that you were trying another approach.
I still don't see how it can fail when using the __asm__ implementation of popcount.
What you could try is to include a line #warning USING POPCNT in bitcount.h, say between lines 99 and 100. If during compilation you don't see USING POPCNT warnings, then somehow the __asm__ is not being used.
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(BITCOUNT_H_INCLUDED)
#define BITCOUNT_H_INCLUDED
#include <cassert>
#include "types.h"
enum BitCountType {
CNT_64,
CNT_64_MAX15,
CNT_32,
CNT_32_MAX15,
CNT_HW_POPCNT
};
/// Determine at compile time the best popcount<> specialization according if
/// platform is 32 or 64 bits, to the maximum number of nonzero bits to count
/// and if hardware popcnt instruction is available.
const BitCountType Full = CNT_HW_POPCNT;
const BitCountType Max15 = CNT_HW_POPCNT;
/// popcount() counts the number of nonzero bits in a bitboard
template<BitCountType type>
inline int popcount(Bitboard b) {
__asm__("popcnt %1, %0" : "=r" (b) : "r" (b));
return b;
}
#endif // !defined(BITCOUNT_H_INCLUDED)
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(BITCOUNT_H_INCLUDED)
#define BITCOUNT_H_INCLUDED
#include <cassert>
#include "types.h"
enum BitCountType {
CNT_64,
CNT_64_MAX15,
CNT_32,
CNT_32_MAX15,
CNT_HW_POPCNT
};
/// Determine at compile time the best popcount<> specialization according if
/// platform is 32 or 64 bits, to the maximum number of nonzero bits to count
/// and if hardware popcnt instruction is available.
const BitCountType Full = CNT_HW_POPCNT;
const BitCountType Max15 = CNT_HW_POPCNT;
/// popcount() counts the number of nonzero bits in a bitboard
template<BitCountType type>
inline int popcount(Bitboard b) {
__asm__("popcnt %1, %0" : "=r" (b) : "r" (b));
return b;
}
#endif // !defined(BITCOUNT_H_INCLUDED)
zullil wrote:It appears that popcnt is being used. The question now becomes why can't I find a popcnt instruction or opcode in the binary!
My only explanation is that otool is somehow not seeing the code sections that have the popcnt instructions. It may not be a very good explanation, but I don't see any other.
On my (linux) system the equivalent tool is objdump. Maybe you have that too and you could try objdump -d ./stockfish | grep popcnt?
zullil wrote:It appears that popcnt is being used. The question now becomes why can't I find a popcnt instruction or opcode in the binary!
My only explanation is that otool is somehow not seeing the code sections that have the popcnt instructions. It may not be a very good explanation, but I don't see any other.
On my (linux) system the equivalent tool is objdump. Maybe you have that too and you could try objdump -d ./stockfish | grep popcnt?
Yes, I considered doing that. But I did search the binary with a hex editor and couldn't locate the popcnt opcodes. (I had no problem locating them in the non-pgo'd binary.) Still mysterious.
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(BITCOUNT_H_INCLUDED)
#define BITCOUNT_H_INCLUDED
#include <cassert>
#include "types.h"
enum BitCountType {
CNT_64,
CNT_64_MAX15,
CNT_32,
CNT_32_MAX15,
CNT_HW_POPCNT
};
/// Determine at compile time the best popcount<> specialization according if
/// platform is 32 or 64 bits, to the maximum number of nonzero bits to count
/// and if hardware popcnt instruction is available.
const BitCountType Full = CNT_HW_POPCNT;
const BitCountType Max15 = CNT_HW_POPCNT;
/// popcount() counts the number of nonzero bits in a bitboard
template<BitCountType type>
inline int popcount(Bitboard b) {
__asm__("popcnt %1, %0" : "=r" (b) : "r" (b));
return b;
}
#endif // !defined(BITCOUNT_H_INCLUDED)
Yes, I tried that too.
If you've tried this and the executable worked correctly, then it must have the popcnt instruction.
Just for fun you could comment out the __asm__ line and confirm that stockfish crashes.
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(BITCOUNT_H_INCLUDED)
#define BITCOUNT_H_INCLUDED
#include <cassert>
#include "types.h"
enum BitCountType {
CNT_64,
CNT_64_MAX15,
CNT_32,
CNT_32_MAX15,
CNT_HW_POPCNT
};
/// Determine at compile time the best popcount<> specialization according if
/// platform is 32 or 64 bits, to the maximum number of nonzero bits to count
/// and if hardware popcnt instruction is available.
const BitCountType Full = CNT_HW_POPCNT;
const BitCountType Max15 = CNT_HW_POPCNT;
/// popcount() counts the number of nonzero bits in a bitboard
template<BitCountType type>
inline int popcount(Bitboard b) {
__asm__("popcnt %1, %0" : "=r" (b) : "r" (b));
return b;
}
#endif // !defined(BITCOUNT_H_INCLUDED)
Yes, I tried that too.
If you've tried this and the executable worked correctly, then it must have the popcnt instruction.
Yes, I knew it had to be there. But I couldn't/can't find it! I even ran the binary on my core 2 duo Macbook, which complained about an "illegal instruction", since that cpu doesn't have popcnt.
Now compile and dump the output of otool to a text file (otool stockfish >assembly.txt).
Load the text file into an editor and look either for main or for $0x1e240 (which is 123456):
zullil wrote:It appears that popcnt is being used. The question now becomes why can't I find a popcnt instruction or opcode in the binary!
My only explanation is that otool is somehow not seeing the code sections that have the popcnt instructions. It may not be a very good explanation, but I don't see any other.
On my (linux) system the equivalent tool is objdump. Maybe you have that too and you could try objdump -d ./stockfish | grep popcnt?
Or you can manually type the gcc compile command (including prof_use) and adding the -s and -c flags. Then you should get a formatted asm file where you can see if there are any popcnt's to be found...