Stockfish POPCNT support with gcc

Discussion of chess software programming and technical issues.

Moderators: Harvey Williamson, bob, hgm

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Post Reply
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Stockfish POPCNT support with gcc

Post by mcostalba » Sun Jan 31, 2010 8:47 am

In case people is interested this is the patch to enable hardware POPCNT support with gcc in Stockfish 1.6.2. Many thanks to Laurent Desnogues for testing.

To compile with POPCNT support do:

Code: Select all

make clean
make gcc-popcnt

Apply the following:

Code: Select all

Date: Sat, 30 Jan 2010 19:18:27 +0100
Subject: [PATCH] Add hardware POPCNT support for gcc

With new target 'make gcc-popcnt' it is now
possible to compile with enabled hardware POPCNT
support also with gcc. Until now was possible only
for Intel and MSVC compilers.

When this instruction is supported by CPU, for instance
on Intel i7 or i5 family, produced binary is a bit faster.

---
 src/Makefile   |    8 ++++++++
 src/bitcount.h |   24 ++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 1388f46..3963e55 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -80,6 +80,7 @@ help:
 	@echo "Makefile options:"
 	@echo ""
 	@echo "make                >  Default: Compiler = g++"
+	@echo "make gcc-popcnt     >  Compiler = g++ + popcnt-support"
 	@echo "make icc            >  Compiler = icpc"
 	@echo "make icc-profile    >  Compiler = icpc + automatic pgo-build"
 	@echo "make icc-profile-popcnt >  Compiler = icpc + automatic pgo-build + popcnt-support"
@@ -108,6 +109,13 @@ gcc:
 	CXXFLAGS="$(GCCFLAGS)" \
 	all
 
+gcc-popcnt:
+	$(MAKE) \
+	CXX='g++' \
+	CXXFLAGS="$(GCCFLAGS) -DUSE_POPCNT" \
+	all
+
+
 icc:
 	$(MAKE) \
 	CXX='icpc' \
diff --git a/src/bitcount.h b/src/bitcount.h
index aa27c04..b32314d 100644
--- a/src/bitcount.h
+++ b/src/bitcount.h
@@ -53,6 +53,30 @@ inline bool cpu_has_popcnt() {
 
 #define POPCNT_INTRINSIC(x) __popcnt64(x)
 
+#elif defined(__GNUC__) && defined(USE_POPCNT) // Gcc compiler
+
+inline void __cpuid(unsigned int op,
+                    unsigned int *eax, unsigned int *ebx,
+                    unsigned int *ecx, unsigned int *edx)
+{
+  *eax = op;
+  *ecx = 0;
+  __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+                  : "0" (*eax), "2" (*ecx));
+}
+
+inline bool cpu_has_popcnt() {
+
+  unsigned int eax, ebx, ecx, edx;
+  __cpuid(1, &eax, &ebx, &ecx, &edx);
+  return (ecx >> 23) & 1;
+}
+
+#define POPCNT_INTRINSIC(x) ({ \
+   unsigned long __ret; \
+   __asm__("popcnt %1, %0" : "=r" (__ret) : "r" (x)); \
+   __ret; })
+
 #else // Safe fallback for unsupported compilers or when USE_POPCNT is disabled
 
 inline bool cpu_has_popcnt() { return false; }
-- 
1.6.5.2.150.g1b52a

ldesnogu

Re: Stockfish POPCNT support with gcc

Post by ldesnogu » Sun Jan 31, 2010 9:55 am

mcostalba wrote:In case people is interested this is the patch to enable hardware POPCNT support with gcc in Stockfish 1.6.2. Many thanks to Laurent Desnogues for testing.

To compile with POPCNT support do:

Code: Select all

make clean
make gcc-popcnt

Apply the following:

Code: Select all

Date: Sat, 30 Jan 2010 19:18:27 +0100
Subject: [PATCH] Add hardware POPCNT support for gcc

With new target 'make gcc-popcnt' it is now
possible to compile with enabled hardware POPCNT
support also with gcc. Until now was possible only
for Intel and MSVC compilers.

When this instruction is supported by CPU, for instance
on Intel i7 or i5 family, produced binary is a bit faster.

---
 src/Makefile   |    8 ++++++++
 src/bitcount.h |   24 ++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 1388f46..3963e55 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -80,6 +80,7 @@ help:
 	@echo "Makefile options:"
 	@echo ""
 	@echo "make                >  Default: Compiler = g++"
+	@echo "make gcc-popcnt     >  Compiler = g++ + popcnt-support"
 	@echo "make icc            >  Compiler = icpc"
 	@echo "make icc-profile    >  Compiler = icpc + automatic pgo-build"
 	@echo "make icc-profile-popcnt >  Compiler = icpc + automatic pgo-build + popcnt-support"
@@ -108,6 +109,13 @@ gcc:
 	CXXFLAGS="$(GCCFLAGS)" \
 	all
 
+gcc-popcnt:
+	$(MAKE) \
+	CXX='g++' \
+	CXXFLAGS="$(GCCFLAGS) -DUSE_POPCNT" \
I think that if you want to force usage of the popcnt instruction with gcc you will have to add -mpopcnt. OTOH if you're compiling on a machine that has support for this instruction that flag is useless.

Code: Select all

+	all
+
+
 icc:
 	$(MAKE) \
 	CXX='icpc' \
diff --git a/src/bitcount.h b/src/bitcount.h
index aa27c04..b32314d 100644
--- a/src/bitcount.h
+++ b/src/bitcount.h
@@ -53,6 +53,30 @@ inline bool cpu_has_popcnt() {
 
 #define POPCNT_INTRINSIC(x) __popcnt64(x)
 
+#elif defined(__GNUC__) && defined(USE_POPCNT) // Gcc compiler
+
+inline void __cpuid(unsigned int op,
+                    unsigned int *eax, unsigned int *ebx,
+                    unsigned int *ecx, unsigned int *edx)
+{
+  *eax = op;
+  *ecx = 0;
+  __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+                  : "0" (*eax), "2" (*ecx));
+}
+
+inline bool cpu_has_popcnt() {
+
+  unsigned int eax, ebx, ecx, edx;
+  __cpuid(1, &eax, &ebx, &ecx, &edx);
+  return (ecx >> 23) & 1;
+}
+
+#define POPCNT_INTRINSIC(x) ({ \
+   unsigned long __ret; \
+   __asm__("popcnt %1, %0" : "=r" (__ret) : "r" (x)); \
+   __ret; })
+
 #else // Safe fallback for unsupported compilers or when USE_POPCNT is disabled
 
 inline bool cpu_has_popcnt() { return false; }
-- 
1.6.5.2.150.g1b52a

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Re: Stockfish POPCNT support with gcc

Post by mcostalba » Sun Jan 31, 2010 11:27 am

ldesnogu wrote: I think that if you want to force usage of the popcnt instruction with gcc you will have to add -mpopcnt. OTOH if you're compiling on a machine that has support for this instruction that flag is useless.
I thought you had already tested the above patch and reported that it works. Am I missing something ?

Regarding -mpopcnt I think is related to use gcc builtins, in this case I have injected popcnt instruction directly by an __asm__ statement.

Also -DUSE_POPCNT is not used by gcc but is passed as is as a define, so that the #elif in the patch is enabled.

ldesnogu

Re: Stockfish POPCNT support with gcc

Post by ldesnogu » Sun Jan 31, 2010 11:35 am

Oh, you're right, I kind of mixed my patch, which uses the builtin, and yours. I guess I should refrain from answering posts too early on a Sunday morning :)

Post Reply