Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
kimwalisch committed Jun 21, 2024
1 parent c2be409 commit 9570ffa
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 80 deletions.
26 changes: 16 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,27 @@ else()
set(LIB_SRC ${LIB_SRC} src/gourdon/AC.cpp)
endif()

# Check if compiler supports CPU multiarch ###########################

if(WITH_MULTIARCH)
include("${PROJECT_SOURCE_DIR}/cmake/multiarch_x86_popcnt.cmake")
include("${PROJECT_SOURCE_DIR}/cmake/multiarch_avx512_vpopcnt.cmake")

if(multiarch_x86_popcnt OR multiarch_avx512_vpopcnt)
set(LIB_SRC ${LIB_SRC} src/x86/cpuid.cpp)
endif()

if(NOT multiarch_avx512_vpopcnt)
include("${PROJECT_SOURCE_DIR}/cmake/multiarch_arm_sve.cmake")
endif()
endif()

# On x86 CPUs compile cpuid.cpp ######################################

include("${PROJECT_SOURCE_DIR}/cmake/x86_cpuid.cmake")

if(x86_cpuid)
set(LIB_SRC ${LIB_SRC} src/arch/x86/cpuid.cpp)
set(LIB_SRC ${LIB_SRC} src/x86/cpuid.cpp)
endif()

# Enable __float128 support (requires libquadmath) ###################
Expand Down Expand Up @@ -196,15 +211,6 @@ include("${PROJECT_SOURCE_DIR}/cmake/compiler_supports_cpp11.cmake")

include("${PROJECT_SOURCE_DIR}/cmake/int128_t.cmake")

# Check if compiler supports x64 multiarch ###########################

if(WITH_MULTIARCH)
include("${PROJECT_SOURCE_DIR}/cmake/multiarch_avx512_vpopcnt.cmake")
if(NOT multiarch_avx512_vpopcnt)
include("${PROJECT_SOURCE_DIR}/cmake/multiarch_arm_sve.cmake")
endif()
endif()

# Check for OpenMP ###################################################

if(WITH_OPENMP)
Expand Down
2 changes: 1 addition & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Changes in primecount-7.14, 2024-06-21

* Move x86 cpuid code from cpuid.hpp to src/arch/x86/cpuid.cpp.
* Move x86 cpuid code from cpuid.hpp to src/x86/cpuid.cpp.
* int128_t.hpp: Rename namespace port to pstd (portable std namespace).
* popcnt.hpp: Improve GCC performance on x86 CPUs.
* Sieve.hpp: Tune AVX512 code.
Expand Down
4 changes: 2 additions & 2 deletions cmake/multiarch_avx512_vpopcnt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ check_cxx_source_compiles("
Error: AVX512 BMI2 multiarch not needed!
#endif
#include <src/arch/x86/cpuid.cpp>
#include <src/x86/cpuid.cpp>
#include <immintrin.h>
#include <stdint.h>
Expand Down Expand Up @@ -75,7 +75,7 @@ check_cxx_source_compiles("
" multiarch_avx512_vpopcnt)

if(multiarch_avx512_vpopcnt)
set(ENABLE_MULTIARCH "ENABLE_MULTIARCH_AVX512_BMI2")
set(ENABLE_MULTIARCH "${ENABLE_MULTIARCH} ENABLE_MULTIARCH_AVX512_BMI2")
endif()

cmake_pop_check_state()
53 changes: 53 additions & 0 deletions cmake/multiarch_x86_popcnt.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# On x86 CPUs we need to enable the use of cpuid.cpp.
# If cpuid.cpp compiles we assume it is a x86 CPU.

include(CheckCXXSourceCompiles)
include(CMakePushCheckState)

cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}")

check_cxx_source_compiles("
// Enable CPUID for POPCNT on x86 and x86-64 CPUs.
// This is required because not all x86 and x86-64 CPUs
// support the POPCNT instruction.
#if !(defined(__x86_64__) || \
defined(__i386__) || \
defined(_M_X64) || \
defined(_M_IX86))
Error: x86 POPCNT multiarch not needed!
#endif
// Both GCC and Clang (even Clang on Windows) define the __POPCNT__
// macro if the user compiles with -mpopcnt. The __POPCNT__
// macro is even defined if the user compiles with other flags
// such as -mavx or -march=native.
#if defined(__POPCNT__)
Error: x86 POPCNT multiarch not needed!
// The MSVC compiler does not support a POPCNT macro, but if the user
// compiles with e.g. /arch:AVX or /arch:AVX512 then MSVC defines
// the __AVX__ macro and POPCNT is also supported.
#elif defined(_MSC_VER) && defined(__AVX__)
Error: x86 POPCNT multiarch not needed!
#endif
#include <src/x86/cpuid.cpp>
#include <iostream>
int main()
{
if (primecount::has_cpuid_popcnt())
std::cout << \"CPU supports POPCNT!\" << std::endl;
else
std::cout << \"CPU does not support POPCNT!\" << std::endl;
return 0;
}
" multiarch_x86_popcnt)

if(multiarch_x86_popcnt)
set(ENABLE_MULTIARCH "${ENABLE_MULTIARCH} ENABLE_MULTIARCH_x86_POPCNT")
endif()

cmake_pop_check_state()
29 changes: 0 additions & 29 deletions cmake/x86_cpuid.cmake

This file was deleted.

28 changes: 0 additions & 28 deletions include/cpu_supports_popcnt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,6 @@
#ifndef CPU_SUPPORTS_POPCNT_HPP
#define CPU_SUPPORTS_POPCNT_HPP

// Enable CPUID for POPCNT on x86 and x86-64 CPUs.
// This is required because not all x86 and x86-64 CPUs
// support the POPCNT instruction.
#if defined(__x86_64__) || \
defined(__i386__) || \
defined(_M_X64) || \
defined(_M_IX86)

// Both GCC and Clang (even Clang on Windows) define the __POPCNT__
// macro if the user compiles with -mpopcnt. The __POPCNT__
// macro is even defined if the user compiles with other flags
// such as -mavx or -march=native.
#if defined(__POPCNT__)
#define HAS_POPCNT

// The MSVC compiler does not support a POPCNT macro, but if the user
// compiles with e.g. /arch:AVX or /arch:AVX512 then MSVC defines
// the __AVX__ macro and POPCNT is also supported.
#elif defined(_MSC_VER) && defined(__AVX__)
#define HAS_POPCNT
#endif

#if !defined(HAS_POPCNT)
#define ENABLE_MULTIARCH_x86_POPCNT

namespace primecount {

bool has_cpuid_popcnt();
Expand All @@ -49,7 +24,4 @@ bool cpu_supports_popcnt = primecount::has_cpuid_popcnt();

} // namespace

#endif // !defined(HAS_POPCNT)
#endif // x86 or x86-64

#endif
6 changes: 4 additions & 2 deletions include/popcnt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
#ifndef POPCNT_HPP
#define POPCNT_HPP

#include <cpu_supports_popcnt.hpp>
#include <macros.hpp>

#include <stdint.h>

#if defined(ENABLE_MULTIARCH_x86_POPCNT)
#include <cpu_supports_popcnt.hpp>
#endif

namespace {

/// This uses fewer arithmetic operations than any other known
Expand Down
20 changes: 12 additions & 8 deletions src/arch/x86/cpuid.cpp → src/x86/cpuid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#define XSTATE_YMM (1 << 2)
#define XSTATE_ZMM (7 << 5)

namespace primecount {
namespace {

void run_cpuid(int eax, int ecx, int* abcd)
{
Expand Down Expand Up @@ -66,13 +66,6 @@ void run_cpuid(int eax, int ecx, int* abcd)
#endif
}

bool has_cpuid_popcnt()
{
int abcd[4];
run_cpuid(1, 0, abcd);
return (abcd[2] & bit_POPCNT) == bit_POPCNT;
}

// Get Value of Extended Control Register
uint64_t get_xcr0()
{
Expand All @@ -87,6 +80,17 @@ uint64_t get_xcr0()
#endif
}

} // namespace

namespace primecount {

bool has_cpuid_popcnt()
{
int abcd[4];
run_cpuid(1, 0, abcd);
return (abcd[2] & bit_POPCNT) == bit_POPCNT;
}

bool has_cpuid_avx512_bmi2()
{
int abcd[4];
Expand Down

0 comments on commit 9570ffa

Please sign in to comment.