CpuInfo.h#
Fully qualified name: carb/extras/CpuInfo.h
File members: carb/extras/CpuInfo.h
// SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
#pragma once
#include "../Architecture.h"
#include "../Compiler.h"
#include <array>
#include <cstdint>
#if CARB_X86_64
# if CARB_COMPILER_MSC
extern "C"
{
void __cpuid(int cpuInfo[4], int function_id);
}
# pragma intrinsic(__cpuid)
# elif CARB_COMPILER_GNUC
// for some strange reason, GCC's 'cpuid.h' header does not have an include guard of any
// kind. This leads to multiple definition errors when the header is included twice in
// a translation unit. To avoid this, we'll add our own external include guard here.
# ifndef CARB_CPUID_H_INCLUDED
# define CARB_CPUID_H_INCLUDED
# include "cpuid.h"
# endif
# else
CARB_UNSUPPORTED_COMPILER();
# endif
#endif
namespace carb::extras
{
namespace detail
{
#if CARB_X86_64
struct cpuid_output
{
unsigned eax, ebx, ecx, edx;
};
inline cpuid_output cpuid(unsigned func)
{
# if CARB_COMPILER_MSC
int regs[4];
__cpuid(regs, int(func));
return { unsigned(regs[0]), unsigned(regs[1]), unsigned(regs[2]), unsigned(regs[3]) };
# elif CARB_COMPILER_GNUC
cpuid_output out = {};
(void)__get_cpuid(func, &out.eax, &out.ebx, &out.ecx, &out.edx);
return out;
# else
CARB_UNSUPPORTED_COMPILER();
# endif
}
#endif
} // namespace detail
class CpuInfo
{
public:
CpuInfo()
{
#if CARB_X86_64
m_data = detail::cpuid(kInfoType);
#endif
}
bool popcntSupported()
{
#if CARB_X86_64
return m_data.ecx & (1UL << kPopCountBit);
#else
return false;
#endif
}
private:
#if CARB_X86_64
static constexpr uint32_t kInfoType = 0x00000001;
static constexpr uint8_t kPopCountBit = 23;
detail::cpuid_output m_data;
#endif
};
} // namespace carb::extras