Source code for libretro.api.perf

"""
Performance counter and SIMD feature detection types.

Corresponds to :c:type:`retro_perf_callback`, :c:type:`retro_perf_counter`,
and the ``RETRO_SIMD_*`` constants in ``libretro.h``.

.. seealso::
    :class:`.PerfDriver`
        The :class:`~typing.Protocol` that uses these types
        to expose performance counting functionality to the :class:`.Core`.

    :mod:`libretro.drivers.perf`
        libretro.py's included :class:`.PerfDriver` implementations.
"""

from ctypes import Structure, c_bool, c_char_p, c_int64, c_uint64
from dataclasses import dataclass
from enum import IntFlag

from libretro.ctypes import TypedFunctionPointer, TypedPointer

RETRO_SIMD_SSE = 1 << 0
RETRO_SIMD_SSE2 = 1 << 1
RETRO_SIMD_VMX = 1 << 2
RETRO_SIMD_VMX128 = 1 << 3
RETRO_SIMD_AVX = 1 << 4
RETRO_SIMD_NEON = 1 << 5
RETRO_SIMD_SSE3 = 1 << 6
RETRO_SIMD_SSSE3 = 1 << 7
RETRO_SIMD_MMX = 1 << 8
RETRO_SIMD_MMXEXT = 1 << 9
RETRO_SIMD_SSE4 = 1 << 10
RETRO_SIMD_SSE42 = 1 << 11
RETRO_SIMD_AVX2 = 1 << 12
RETRO_SIMD_VFPU = 1 << 13
RETRO_SIMD_PS = 1 << 14
RETRO_SIMD_AES = 1 << 15
RETRO_SIMD_VFPV3 = 1 << 16
RETRO_SIMD_VFPV4 = 1 << 17
RETRO_SIMD_POPCNT = 1 << 18
RETRO_SIMD_MOVBE = 1 << 19
RETRO_SIMD_CMOV = 1 << 20
RETRO_SIMD_ASIMD = 1 << 21


retro_perf_tick_t = c_uint64
"""A performance counter tick value."""

retro_time_t = c_int64
"""A timestamp in microseconds."""


[docs] class CpuFeatures(IntFlag): """ SIMD instruction set flags reported by the host CPU. Corresponds to the ``RETRO_SIMD_*`` constants in ``libretro.h``. >>> from libretro.api import CpuFeatures >>> CpuFeatures.SSE <CpuFeatures.SSE: 1> """ SSE = RETRO_SIMD_SSE SSE2 = RETRO_SIMD_SSE2 VMX = RETRO_SIMD_VMX VMX128 = RETRO_SIMD_VMX128 AVX = RETRO_SIMD_AVX NEON = RETRO_SIMD_NEON SSE3 = RETRO_SIMD_SSE3 SSSE3 = RETRO_SIMD_SSSE3 MMX = RETRO_SIMD_MMX MMXEXT = RETRO_SIMD_MMXEXT SSE4 = RETRO_SIMD_SSE4 SSE42 = RETRO_SIMD_SSE42 AVX2 = RETRO_SIMD_AVX2 VFPU = RETRO_SIMD_VFPU PS = RETRO_SIMD_PS AES = RETRO_SIMD_AES VFPV3 = RETRO_SIMD_VFPV3 VFPV4 = RETRO_SIMD_VFPV4 POPCNT = RETRO_SIMD_POPCNT MOVBE = RETRO_SIMD_MOVBE CMOV = RETRO_SIMD_CMOV ASIMD = RETRO_SIMD_ASIMD
[docs] @dataclass(init=False, slots=True) class retro_perf_counter(Structure): """ A named performance counter for profiling hot code paths within a :class:`.Core`. Corresponds to :c:type:`retro_perf_counter` in ``libretro.h``. >>> from libretro.api import retro_perf_counter >>> c = retro_perf_counter() >>> c.registered False """ ident: bytes | None """Human-readable identifier for this counter.""" start: int """Tick value at the most recent start of measurement.""" total: int """Total accumulated ticks for this counter.""" call_cnt: int """Number of times this counter has been started.""" registered: bool """Whether this counter has been registered with the frontend.""" _fields_ = ( ("ident", c_char_p), ("start", retro_perf_tick_t), ("total", retro_perf_tick_t), ("call_cnt", retro_perf_tick_t), ("registered", c_bool), )
[docs] def __deepcopy__(self, _): """ Return a deep copy of this object, including all strings. Intended for use with :func:`copy.deepcopy`. """ return retro_perf_counter( self.ident, self.start, self.total, self.call_cnt, self.registered, )
retro_perf_get_time_usec_t = TypedFunctionPointer[retro_time_t, []] """ Return the current system time in microseconds. Registered by the :term:`frontend` and called by the :term:`core`. The frontend should use the most accurate timer available on the platform. :return: The current time, in microseconds. Corresponds to :c:type:`retro_perf_get_time_usec_t` in ``libretro.h``. """ retro_perf_get_counter_t = TypedFunctionPointer[retro_perf_tick_t, []] """ Return the number of ticks elapsed since some unspecified epoch. Registered by the :term:`frontend` and called by the :term:`core`. The exact meaning of a tick depends on the platform (typically nanoseconds or CPU cycles). :return: The current tick count. Corresponds to :c:type:`retro_perf_get_counter_t` in ``libretro.h``. """ retro_get_cpu_features_t = TypedFunctionPointer[c_uint64, []] """ Return a bitmask of detected CPU features. Registered by the :term:`frontend` and called by the :term:`core` to dispatch CPU-specific code paths at runtime. :return: A bitmask of :class:`CpuFeatures` flags. Corresponds to :c:type:`retro_get_cpu_features_t` in ``libretro.h``. """ retro_perf_log_t = TypedFunctionPointer[None, []] """ Log or display the state of every registered performance counter. Registered by the :term:`frontend` and called by the :term:`core`. The exact presentation is up to the frontend. Corresponds to :c:type:`retro_perf_log_t` in ``libretro.h``. """ retro_perf_register_t = TypedFunctionPointer[None, [TypedPointer[retro_perf_counter]]] """ Register a performance counter with the frontend. Registered by the :term:`frontend` and called by the :term:`core` once per counter, before the counter is started or stopped. :param counter: Pointer to a :class:`retro_perf_counter` to register. Its :attr:`~retro_perf_counter.ident` field must be set; all other fields must be zero or :obj:`False`. Corresponds to :c:type:`retro_perf_register_t` in ``libretro.h``. """ retro_perf_start_t = TypedFunctionPointer[None, [TypedPointer[retro_perf_counter]]] """ Start timing a registered performance counter. Registered by the :term:`frontend` and called by the :term:`core` right before the code being measured. :param counter: Pointer to a :class:`retro_perf_counter` that has been registered with :c:type:`retro_perf_register_t`. Corresponds to :c:type:`retro_perf_start_t` in ``libretro.h``. """ retro_perf_stop_t = TypedFunctionPointer[None, [TypedPointer[retro_perf_counter]]] """ Stop timing a registered performance counter. Registered by the :term:`frontend` and called by the :term:`core` right after the code being measured; the elapsed time is added to the counter's :attr:`~retro_perf_counter.total`. :param counter: Pointer to the same :class:`retro_perf_counter` that was previously passed to :c:type:`retro_perf_start_t`. Corresponds to :c:type:`retro_perf_stop_t` in ``libretro.h``. """
[docs] @dataclass(init=False, slots=True) class retro_perf_callback(Structure): """ Provides functions for performance profiling and CPU feature detection. Corresponds to :c:type:`retro_perf_callback` in ``libretro.h``. """ get_time_usec: retro_perf_get_time_usec_t | None """Returns the current time in microseconds.""" get_cpu_features: retro_get_cpu_features_t | None """Returns a bitmask of :class:`CpuFeatures`.""" get_perf_counter: retro_perf_get_counter_t | None """Returns the current performance counter tick value.""" perf_register: retro_perf_register_t | None """Registers a performance counter.""" perf_start: retro_perf_start_t | None """Starts a performance counter.""" perf_stop: retro_perf_stop_t | None """Stops a performance counter.""" perf_log: retro_perf_log_t | None """Logs all registered performance counters.""" _fields_ = ( ("get_time_usec", retro_perf_get_time_usec_t), ("get_cpu_features", retro_get_cpu_features_t), ("get_perf_counter", retro_perf_get_counter_t), ("perf_register", retro_perf_register_t), ("perf_start", retro_perf_start_t), ("perf_stop", retro_perf_stop_t), ("perf_log", retro_perf_log_t), )
[docs] def __deepcopy__(self, _): """ Return a deep copy of this object. Intended for use with :func:`copy.deepcopy`. >>> import copy >>> from libretro.api import retro_perf_callback >>> copy.deepcopy(retro_perf_callback()).get_time_usec is None True """ return retro_perf_callback( self.get_time_usec, self.get_cpu_features, self.get_perf_counter, self.perf_register, self.perf_start, self.perf_stop, self.perf_log, )
__all__ = [ "CpuFeatures", "retro_perf_counter", "retro_perf_get_time_usec_t", "retro_perf_get_counter_t", "retro_get_cpu_features_t", "retro_perf_log_t", "retro_perf_register_t", "retro_perf_start_t", "retro_perf_stop_t", "retro_perf_callback", "retro_time_t", "retro_perf_tick_t", ]