ClickHouse/src/Functions/TargetSpecific.cpp

59 lines
1.5 KiB
C++
Raw Normal View History

#include <Functions/TargetSpecific.h>
2020-04-02 13:48:14 +00:00
2020-04-14 15:46:53 +00:00
#if defined(__GNUC__)
2020-04-06 07:31:26 +00:00
# include <cpuid.h>
2020-05-15 10:10:34 +00:00
# include <x86intrin.h>
2020-04-06 07:31:26 +00:00
#else
# error "Only CLANG and GCC compilers are supported for dynamic dispatch"
#endif
namespace DB
2020-04-02 13:48:14 +00:00
{
2020-05-15 10:10:34 +00:00
__attribute__ ((target("xsave")))
uint64_t xgetbv(uint32_t ecx) {
return _xgetbv(ecx);
}
2020-04-06 07:31:26 +00:00
int GetSupportedArches() {
unsigned int eax, ebx, ecx, edx;
if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
return 0;
}
int res = 0;
if (ecx & bit_SSE4_2)
res |= static_cast<int>(TargetArch::SSE4);
2020-05-15 10:10:34 +00:00
// (xgetbv(0) & 0x6) == 0x6 checks that XMM state and YMM state are enabled.
if ((ecx & bit_OSXSAVE) && (ecx & bit_AVX) && (xgetbv(0) & 0x6) == 0x6) {
2020-04-06 07:31:26 +00:00
res |= static_cast<int>(TargetArch::AVX);
if (__get_cpuid(7, &eax, &ebx, &ecx, &edx) && (ebx & bit_AVX2)) {
res |= static_cast<int>(TargetArch::AVX2);
2020-05-15 10:10:34 +00:00
if (ebx & bit_AVX512F) {
res |= static_cast<int>(TargetArch::AVX512f);
}
2020-04-06 07:31:26 +00:00
}
}
return res;
}
2020-04-02 13:48:14 +00:00
bool IsArchSupported(TargetArch arch)
{
2020-04-06 07:31:26 +00:00
static int arches = GetSupportedArches();
return arch == TargetArch::Default || (arches & static_cast<int>(arch));
2020-04-02 13:48:14 +00:00
}
2020-05-15 10:10:34 +00:00
String ToString(TargetArch arch)
{
switch (arch) {
case TargetArch::Default: return "default";
case TargetArch::SSE4: return "sse4";
case TargetArch::AVX: return "avx";
case TargetArch::AVX2: return "avx2";
case TargetArch::AVX512f: return "avx512f";
}
__builtin_unreachable();
}
} // namespace DB