cpuinfo

repository·main·Indexed 22 days ago

https://github.com/pytorch/cpuinfo

A high-performance, cross-platform C/C++ library used to detect CPU hardware details, including instruction sets (up to AVX512 and ARMv8.3), microarchitecture, cache hierarchy, and topology. It provides thread-safe access to host CPU information for runtime performance optimizations across Linux, Windows, macOS, Android, iOS, and FreeBSD.

Tokens
2.2K
Snippets
7
Records
9
Agent score
29%

What's inside cpuinfo

  1. Overview of the CPU INFOrmation library

    main

    cpuinfo is a cross-platform C/C++ library designed to detect essential host CPU information required for performance optimization. It provides thread-safe access to CPU details with no memory allocation after initialization and no exceptions thrown.

    Key Capabilities:

    • Instruction Set Detection: Supports up to AVX512 (x86) and ARMv8.3 extensions.
    • SoC & Core Info: Detects processor names, vendors, and microarchitectures (including support for heterogeneous cores like big.LITTLE).
    • Cache Information: Provides details on cache type, size, line size, associativity, and topology.
    • Topology Information: Maps relationships between logical processors, cores, and processor packages.

    Supported Platforms:

    • Linux: x86, x86-64, 32-bit ARM, ARM64
    • Windows: x86, x86-64, arm64
    • macOS: x86, x86-64, ARM64 (Apple silicon)
    • Android: x86, x86_64, armeabi, armeabiv7-a, arm64-v8a
    • iOS: x86, x86-64, ARMv7, ARM64
    • FreeBSD: x86-64
  2. Use clog for C-style logging

    main
    clog is a C-style (printf-style) logging library designed for logging errors, warnings, information, and debug messages. It supports independent logging settings for different modules and targets different outputs based on the platform: logcat on Android, and stderr/stdout on other platforms. It is compatible with both C99 and C++.
  3. Integrate libcpuinfo using pkg-config

    main

    The library generates a libcpuinfo.pc manifest by default. You can use pkg-config to retrieve the necessary compiler and linker flags.

    Verify installation via Command Line

    # Check flags and libraries
    $ pkg-config --cflags --libs libcpuinfo
    
    # If installed in a non-standard prefix, set PKG_CONFIG_PATH
    $ PKG_CONFIG_PATH="/path/to/cpuinfo/prefix/lib/pkgconfig/" pkg-config --cflags --libs libcpuinfo

    Use in Makefile

    CFLAGS+= $(pkg-config --cflags libcpuinfo)
    LDFLAGS+= $(pkg-config --libs libcpuinfo)
    CFLAGS+= $(pkg-config --cflags libcpuinfo)
    LDFLAGS+= $(pkg-config --libs libcpuinfo)
  4. Integrate libcpuinfo with CMake

    main

    Use the FindPkgConfig module to locate the library and link against the imported target.

    cmake_minimum_required(VERSION 3.6)
    project("MyCpuInfoProject")
    
    find_package(PkgConfig)
    pkg_check_modules(CpuInfo REQUIRED IMPORTED_TARGET libcpuinfo)
    
    add_executable(${PROJECT_NAME} main.cpp)
    target_link_libraries(${PROJECT_NAME} PkgConfig::CpuInfo)
    find_package(PkgConfig)
    pkg_check_modules(CpuInfo REQUIRED IMPORTED_TARGET libcpuinfo)
    
    add_executable(${PROJECT_NAME} main.cpp)
    target_link_libraries(${PROJECT_NAME} PkgConfig::CpuInfo)
  5. Integrate libcpuinfo with Bazel

    main

    You can fetch cpuinfo from the Bazel Central Registry or override it with a specific commit hash.

    Configure MODULE.bazel

    # Fetch from Bazel Central Registry
    bazel_dep(name = "cpuinfo", version = "0.0.0-20250925-877328f")
    
    # Optional: Override with a specific commit
    git_override(
        module_name = "cpuinfo",
        commit = "<replace_with_commit_hash>",
        remote = "https://github.com/pytorch/cpuinfo.git",
    )

    Configure BUILD

    Add @cpuinfo to your deps:

    cc_binary(
        name = "cpuinfo_test",
        srcs = [
            # ...
        ],
        deps = [
            "@cpuinfo",
        ],
    )
    bazel_dep(name = "cpuinfo", version = "0.0.0-20250925-877328f")
  6. Integrate libcpuinfo with GNU Autotools

    main

    Add the following snippet to your configure.ac to check for the library and set your project's CXXFLAGS and LIBS:

    # CPU INFOrmation library...
    PKG_CHECK_MODULES(
        [libcpuinfo], [libcpuinfo], [],
        [AC_MSG_ERROR([libcpuinfo missing...])])
    YOURPROJECT_CXXFLAGS="$YOURPROJECT_CXXFLAGS $libcpuinfo_CFLAGS"
    YOURPROJECT_LIBS="$YOURPROJECT_LIBS $libcpuinfo_LIBS"
    PKG_CHECK_MODULES(
        [libcpuinfo], [libcpuinfo], [],
        [AC_MSG_ERROR([libcpuinfo missing...])])
    YOURPROJECT_CXXFLAGS="$YOURPROJECT_CXXFLAGS $libcpuinfo_CFLAGS"
    YOURPROJECT_LIBS="$YOURPROJECT_LIBS $libcpuinfo_LIBS"
  7. Integrate libcpuinfo with Meson

    main

    Add dependency('libcpuinfo') to your executable definition in your meson.build file.

    project(
        'MyCpuInfoProject',
        'cpp',
        meson_version: '>=0.55.0'
    )
    
    executable(
        'MyCpuInfoExecutable',
        sources: 'main.cpp',
        dependencies: dependency('libcpuinfo')
    )
    executable(
        'MyCpuInfoExecutable',
        sources: 'main.cpp',
        dependencies: dependency('libcpuinfo')
    )
  8. Define and use module-specific loggers in clog

    main

    To use clog in a module, you must first define the logging functions for that module using the CLOG_DEFINE_LOG_* macros. This allows you to specify a prefix, a module name, and a log level. Once defined, you can use the generated functions (which follow the pattern prefix_log_<level>) to log messages using printf-style formatting.

    Commonly used macros for definition:

    • CLOG_DEFINE_LOG_DEBUG(prefix, name, level)
    • CLOG_DEFINE_LOG_INFO(prefix, name, level)
    • CLOG_DEFINE_LOG_WARNING(prefix, name, level)
    • CLOG_DEFINE_LOG_ERROR(prefix, name, level)
    #include <clog.h>
    
    #ifndef MYMODULE_LOG_LEVEL
        #define MYMODULE_LOG_LEVEL CLOG_DEBUG
    #endif
    
    // Define loggers for the module
    CLOG_DEFINE_LOG_DEBUG(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
    CLOG_DEFINE_LOG_INFO(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
    CLOG_DEFINE_LOG_WARNING(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
    CLOG_DEFINE_LOG_ERROR(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
    
    void some_function(int status, uint32_t expected_zero, void* usually_non_null, float a) {
        if (status != 0) {
            // Uses the error logger
            mymodule_log_error(
                "something really bad happened: "
                "operation failed with status %d", status);
        }
    
        if (expected_zero != 0) {
            // Uses the warning logger
            mymodule_log_warning(
                "something suspicious happened (var = %"PRIu32"), "
                "fall back to generic implementation", expected_zero);
        }
    
        if (usually_non_null == NULL) {
            // Uses the info logger
            mymodule_log_info(
                "something unusual, but common, happened: "
                "enabling work-around");
        }
    
        // Uses the debug logger
        mymodule_log_debug("computed a = %.7f", a);
    }
  9. Common CPU detection tasks with cpuinfo

    main

    The library provides several C functions to query CPU capabilities and topology. Note that most operations require calling cpuinfo_initialize() first.

    Log Processor Name

    cpuinfo_initialize();
    printf("Running on %s CPU\n", cpuinfo_get_package(0)->name);

    Check Instruction Set Support (ARM NEON or x86 AVX)

    cpuinfo_initialize();
    if (cpuinfo_has_arm_neon()) {
        neon_implementation(arguments);
    }
    
    if (cpuinfo_has_x86_avx()) {
        avx_implementation(arguments);
    }

    Identify Microarchitecture

    Use cpuinfo_get_current_core()->uarch to check for specific core types (e.g., Cortex-A53).

    cpuinfo_initialize();
    switch (cpuinfo_get_current_core()->uarch) {
        case cpuinfo_uarch_cortex_a53:
            cortex_a53_implementation(arguments);
            break;
        default:
            generic_implementation(arguments);
            break;
    }

    Access Cache Information

    Get the size of the L1 data cache on the fastest core:

    cpuinfo_initialize();
    const size_t l1_size = cpuinfo_get_processor(0)->cache.l1d->size;

    Pin Thread to Cores Sharing L2 Cache (Linux/Android)

    cpuinfo_initialize();
    cpu_set_t cpu_set;
    CPU_ZERO(&cpu_set);
    const struct cpuinfo_cache* current_l2 = cpuinfo_get_current_processor()->cache.l2;
    for (uint32_t i = 0; i < current_l2->processor_count; i++) {
        CPU_SET(cpuinfo_get_processor(current_l2->processor_start + i)->linux_id, &cpu_set);
    }
    pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set);
    cpuinfo_initialize();
    if (cpuinfo_has_x86_avx()) {
        avx_implementation(arguments);
    }