SDL  2.0
SDL_cpuinfo.h File Reference
#include "SDL_stdinc.h"
#include <immintrin.h>
#include "begin_code.h"
#include "close_code.h"
+ Include dependency graph for SDL_cpuinfo.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SDL_CACHELINE_SIZE   128
 

Functions

int SDL_GetCPUCount (void)
 
int SDL_GetCPUCacheLineSize (void)
 
SDL_bool SDL_HasRDTSC (void)
 
SDL_bool SDL_HasAltiVec (void)
 
SDL_bool SDL_HasMMX (void)
 
SDL_bool SDL_Has3DNow (void)
 
SDL_bool SDL_HasSSE (void)
 
SDL_bool SDL_HasSSE2 (void)
 
SDL_bool SDL_HasSSE3 (void)
 
SDL_bool SDL_HasSSE41 (void)
 
SDL_bool SDL_HasSSE42 (void)
 
SDL_bool SDL_HasAVX (void)
 
SDL_bool SDL_HasAVX2 (void)
 
SDL_bool SDL_HasAVX512F (void)
 
SDL_bool SDL_HasARMSIMD (void)
 
SDL_bool SDL_HasNEON (void)
 
int SDL_GetSystemRAM (void)
 
size_t SDL_SIMDGetAlignment (void)
 Report the alignment this system needs for SIMD allocations. More...
 
voidSDL_SIMDAlloc (const size_t len)
 Allocate memory in a SIMD-friendly way. More...
 
voidSDL_SIMDRealloc (void *mem, const size_t len)
 Reallocate memory obtained from SDL_SIMDAlloc. More...
 
void SDL_SIMDFree (void *ptr)
 Deallocate memory obtained from SDL_SIMDAlloc. More...
 

Detailed Description

CPU feature detection for SDL.

Definition in file SDL_cpuinfo.h.

Macro Definition Documentation

◆ SDL_CACHELINE_SIZE

#define SDL_CACHELINE_SIZE   128

Definition at line 114 of file SDL_cpuinfo.h.

Function Documentation

◆ SDL_GetCPUCacheLineSize()

int SDL_GetCPUCacheLineSize ( void  )

This function returns the L1 cache line size of the CPU

This is useful for determining multi-threaded structure padding or SIMD prefetch sizes.

Definition at line 133 of file SDL_dynapi_procs.h.

References cpuid, d, SDL_CACHELINE_SIZE, SDL_GetCPUType(), SDL_strcmp, and void.

◆ SDL_GetCPUCount()

int SDL_GetCPUCount ( void  )

This function returns the number of CPU cores available.

Definition at line 562 of file SDL_cpuinfo.c.

563 {
564  if (!SDL_CPUCount) {
565 #ifndef SDL_CPUINFO_DISABLED
566 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
567  if (SDL_CPUCount <= 0) {
568  SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
569  }
570 #endif
571 #ifdef HAVE_SYSCTLBYNAME
572  if (SDL_CPUCount <= 0) {
573  size_t size = sizeof(SDL_CPUCount);
574  sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0);
575  }
576 #endif
577 #ifdef __WIN32__
578  if (SDL_CPUCount <= 0) {
579  SYSTEM_INFO info;
580  GetSystemInfo(&info);
581  SDL_CPUCount = info.dwNumberOfProcessors;
582  }
583 #endif
584 #ifdef __OS2__
585  if (SDL_CPUCount <= 0) {
586  DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS,
587  &SDL_CPUCount, sizeof(SDL_CPUCount) );
588  }
589 #endif
590 #endif
591  /* There has to be at least 1, right? :) */
592  if (SDL_CPUCount <= 0) {
593  SDL_CPUCount = 1;
594  }
595  }
596  return SDL_CPUCount;
597 }
static int SDL_CPUCount
Definition: SDL_cpuinfo.c:559
GLsizeiptr size
#define NULL
Definition: begin_code.h:163
typedef int(__stdcall *FARPROC)()

References int(), NULL, and SDL_CPUCount.

◆ SDL_GetSystemRAM()

int SDL_GetSystemRAM ( void  )

This function returns the amount of RAM configured in the system, in MB.

Definition at line 143 of file SDL_dynapi_procs.h.

References int(), NULL, and SDL_SystemRAM.

◆ SDL_Has3DNow()

SDL_bool SDL_Has3DNow ( void  )

This function returns true if the CPU has 3DNow! features.

Definition at line 137 of file SDL_dynapi_procs.h.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_3DNOW.

◆ SDL_HasAltiVec()

SDL_bool SDL_HasAltiVec ( void  )

This function returns true if the CPU has AltiVec features.

Definition at line 135 of file SDL_dynapi_procs.h.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_ALTIVEC.

◆ SDL_HasARMSIMD()

SDL_bool SDL_HasARMSIMD ( void  )

This function returns true if the CPU has ARM SIMD (ARMv6) features.

Definition at line 872 of file SDL_cpuinfo.c.

873 {
875 }
#define CPU_HAS_ARM_SIMD
Definition: SDL_cpuinfo.c:116
#define CPU_FEATURE_AVAILABLE(f)
Definition: SDL_cpuinfo.c:798

References CPU_FEATURE_AVAILABLE, and CPU_HAS_ARM_SIMD.

◆ SDL_HasAVX()

SDL_bool SDL_HasAVX ( void  )

This function returns true if the CPU has AVX features.

Definition at line 599 of file SDL_dynapi_procs.h.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX.

◆ SDL_HasAVX2()

SDL_bool SDL_HasAVX2 ( void  )

This function returns true if the CPU has AVX2 features.

Definition at line 860 of file SDL_cpuinfo.c.

861 {
863 }
#define CPU_HAS_AVX2
Definition: SDL_cpuinfo.c:113

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX2.

◆ SDL_HasAVX512F()

SDL_bool SDL_HasAVX512F ( void  )

This function returns true if the CPU has AVX-512F (foundation) features.

Definition at line 866 of file SDL_cpuinfo.c.

867 {
869 }
#define CPU_HAS_AVX512F
Definition: SDL_cpuinfo.c:115

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX512F.

◆ SDL_HasMMX()

SDL_bool SDL_HasMMX ( void  )

This function returns true if the CPU has MMX features.

Definition at line 812 of file SDL_cpuinfo.c.

813 {
815 }
#define CPU_HAS_MMX
Definition: SDL_cpuinfo.c:105

References CPU_FEATURE_AVAILABLE, and CPU_HAS_MMX.

◆ SDL_HasNEON()

SDL_bool SDL_HasNEON ( void  )

This function returns true if the CPU has NEON (ARM SIMD) features.

Definition at line 652 of file SDL_dynapi_procs.h.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_NEON.

◆ SDL_HasRDTSC()

SDL_bool SDL_HasRDTSC ( void  )

This function returns true if the CPU has the RDTSC instruction.

Definition at line 800 of file SDL_cpuinfo.c.

801 {
803 }
#define CPU_HAS_RDTSC
Definition: SDL_cpuinfo.c:103

References CPU_FEATURE_AVAILABLE, and CPU_HAS_RDTSC.

◆ SDL_HasSSE()

SDL_bool SDL_HasSSE ( void  )

This function returns true if the CPU has SSE features.

Definition at line 824 of file SDL_cpuinfo.c.

825 {
827 }
#define CPU_HAS_SSE
Definition: SDL_cpuinfo.c:107

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE.

◆ SDL_HasSSE2()

SDL_bool SDL_HasSSE2 ( void  )

This function returns true if the CPU has SSE2 features.

Definition at line 139 of file SDL_dynapi_procs.h.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE2.

◆ SDL_HasSSE3()

SDL_bool SDL_HasSSE3 ( void  )

This function returns true if the CPU has SSE3 features.

Definition at line 836 of file SDL_cpuinfo.c.

837 {
839 }
#define CPU_HAS_SSE3
Definition: SDL_cpuinfo.c:109

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE3.

◆ SDL_HasSSE41()

SDL_bool SDL_HasSSE41 ( void  )

This function returns true if the CPU has SSE4.1 features.

Definition at line 141 of file SDL_dynapi_procs.h.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE41.

◆ SDL_HasSSE42()

SDL_bool SDL_HasSSE42 ( void  )

This function returns true if the CPU has SSE4.2 features.

Definition at line 848 of file SDL_cpuinfo.c.

849 {
851 }
#define CPU_HAS_SSE42
Definition: SDL_cpuinfo.c:111

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE42.

◆ SDL_SIMDAlloc()

void* SDL_SIMDAlloc ( const size_t  len)

Allocate memory in a SIMD-friendly way.

This will allocate a block of memory that is suitable for use with SIMD instructions. Specifically, it will be properly aligned and padded for the system's supported vector instructions.

The memory returned will be padded such that it is safe to read or write an incomplete vector at the end of the memory block. This can be useful so you don't have to drop back to a scalar fallback at the end of your SIMD processing loop to deal with the final elements without overflowing the allocated buffer.

You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or delete[], etc.

Note that SDL will only deal with SIMD instruction sets it is aware of; for example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants 64. To be clear: if you can't decide to use an instruction set with an SDL_Has*() function, don't use that instruction set with memory allocated through here.

SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't out of memory.

Parameters
lenThe length, in bytes, of the block to allocated. The actual allocated block might be larger due to padding, etc.
Returns
Pointer to newly-allocated block, NULL if out of memory.
See also
SDL_SIMDAlignment
SDL_SIMDRealloc
SDL_SIMDFree

Definition at line 957 of file SDL_cpuinfo.c.

958 {
959  const size_t alignment = SDL_SIMDGetAlignment();
960  const size_t padding = alignment - (len % alignment);
961  const size_t padded = (padding != alignment) ? (len + padding) : len;
962  Uint8 *retval = NULL;
963  Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
964  if (ptr) {
965  /* store the actual malloc pointer right before our aligned pointer. */
966  retval = ptr + sizeof (void *);
967  retval += alignment - (((size_t) retval) % alignment);
968  *(((void **) retval) - 1) = ptr;
969  }
970  return retval;
971 }
unsigned int size_t
size_t SDL_SIMDGetAlignment(void)
Report the alignment this system needs for SIMD allocations.
Definition: SDL_cpuinfo.c:947
#define SDL_malloc
GLenum GLsizei len
uint8_t Uint8
Definition: SDL_stdinc.h:185
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
SDL_bool retval

References NULL, ptr, retval, SDL_malloc, and SDL_SIMDGetAlignment().

◆ SDL_SIMDFree()

void SDL_SIMDFree ( void ptr)

Deallocate memory obtained from SDL_SIMDAlloc.

It is not valid to use this function on a pointer from anything but SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, SDL_malloc, memalign, new[], etc.

However, SDL_SIMDFree(NULL) is a legal no-op.

See also
SDL_SIMDAlloc
SDL_SIMDRealloc

Definition at line 1026 of file SDL_cpuinfo.c.

1027 {
1028  if (ptr) {
1029  void **realptr = (void **) ptr;
1030  realptr--;
1031  SDL_free(*(((void **) ptr) - 1));
1032  }
1033 }
#define SDL_free

References ptr, and SDL_free.

◆ SDL_SIMDGetAlignment()

size_t SDL_SIMDGetAlignment ( void  )

Report the alignment this system needs for SIMD allocations.

This will return the minimum number of bytes to which a pointer must be aligned to be compatible with SIMD instructions on the current machine. For example, if the machine supports SSE only, it will return 16, but if it supports AVX-512F, it'll return 64 (etc). This only reports values for instruction sets SDL knows about, so if your SDL build doesn't have SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and not 64 for the AVX-512 instructions that exist but SDL doesn't know about. Plan accordingly.

Definition at line 773 of file SDL_dynapi_procs.h.

References SDL_assert, SDL_GetCPUFeatures(), and SDL_SIMDAlignment.

Referenced by SDL_SIMDAlloc(), and SDL_SIMDRealloc().

◆ SDL_SIMDRealloc()

void* SDL_SIMDRealloc ( void mem,
const size_t  len 
)

Reallocate memory obtained from SDL_SIMDAlloc.

It is not valid to use this function on a pointer from anything but SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, SDL_malloc, memalign, new[], etc.

Parameters
memThe pointer obtained from SDL_SIMDAlloc. This function also accepts NULL, at which point this function is the same as calling SDL_realloc with a NULL pointer.
lenThe length, in bytes, of the block to allocated. The actual allocated block might be larger due to padding, etc. Passing 0 will return a non-NULL pointer, assuming the system isn't out of memory.
Returns
Pointer to newly-reallocated block, NULL if out of memory.
See also
SDL_SIMDAlignment
SDL_SIMDAlloc
SDL_SIMDFree

Definition at line 974 of file SDL_cpuinfo.c.

975 {
976  const size_t alignment = SDL_SIMDGetAlignment();
977  const size_t padding = alignment - (len % alignment);
978  const size_t padded = (padding != alignment) ? (len + padding) : len;
979  Uint8 *retval = (Uint8*) mem;
980  void *oldmem = mem;
981  size_t memdiff = 0, ptrdiff;
982  Uint8 *ptr;
983 
984  if (mem) {
985  void **realptr = (void **) mem;
986  realptr--;
987  mem = *(((void **) mem) - 1);
988 
989  /* Check the delta between the real pointer and user pointer */
990  memdiff = ((size_t) oldmem) - ((size_t) mem);
991  }
992 
993  ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
994 
995  if (ptr == mem) {
996  return retval; /* Pointer didn't change, nothing to do */
997  }
998  if (ptr == NULL) {
999  return NULL; /* Out of memory, bail! */
1000  }
1001 
1002  /* Store the actual malloc pointer right before our aligned pointer. */
1003  retval = ptr + sizeof (void *);
1004  retval += alignment - (((size_t) retval) % alignment);
1005 
1006  /* Make sure the delta is the same! */
1007  if (mem) {
1008  ptrdiff = ((size_t) retval) - ((size_t) ptr);
1009  if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */
1010  oldmem = (void*) (((size_t) ptr) + memdiff);
1011 
1012  /* Even though the data past the old `len` is undefined, this is the
1013  * only length value we have, and it guarantees that we copy all the
1014  * previous memory anyhow.
1015  */
1016  SDL_memmove(retval, oldmem, len);
1017  }
1018  }
1019 
1020  /* Actually store the malloc pointer, finally. */
1021  *(((void **) retval) - 1) = ptr;
1022  return retval;
1023 }
#define SDL_realloc
#define SDL_memmove

References NULL, ptr, retval, SDL_memmove, SDL_realloc, and SDL_SIMDGetAlignment().