Commit fb824f9a authored by Sam Lantinga's avatar Sam Lantinga

Added cache line size info in SDL_cpuinfo.h

I also added an implementation to dynamically query it, but didn't expose it since most x86 CPUs have an L1 cache line size of 64 bytes.
parent 1d518f0d
...@@ -39,6 +39,11 @@ extern "C" { ...@@ -39,6 +39,11 @@ extern "C" {
/* *INDENT-ON* */ /* *INDENT-ON* */
#endif #endif
/* This is a guess for the cacheline size used for padding, and is correct
* for most x86 processors at this point.
*/
#define SDL_CACHELINE_SIZE 64
/** /**
* This function returns the number of CPU cores available. * This function returns the number of CPU cores available.
*/ */
......
...@@ -337,67 +337,26 @@ SDL_GetCPUCount() ...@@ -337,67 +337,26 @@ SDL_GetCPUCount()
static const char * static const char *
SDL_GetCPUType() SDL_GetCPUType()
{ {
static char SDL_CPUType[48]; static char SDL_CPUType[13];
if (!SDL_CPUType[0]) { if (!SDL_CPUType[0]) {
int i = 0; int i = 0;
int a, b, c, d; int a, b, c, d;
if (CPU_haveCPUID()) { if (CPU_haveCPUID()) {
cpuid(0x80000000, a, b, c, d); cpuid(0x00000000, a, b, c, d);
if (a >= 0x80000004) {
cpuid(0x80000002, a, b, c, d);
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
cpuid(0x80000003, a, b, c, d);
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
cpuid(0x80000004, a, b, c, d);
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
}
} }
if (!SDL_CPUType[0]) { if (!SDL_CPUType[0]) {
SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType)); SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType));
...@@ -406,6 +365,99 @@ SDL_GetCPUType() ...@@ -406,6 +365,99 @@ SDL_GetCPUType()
return SDL_CPUType; return SDL_CPUType;
} }
static const char *
SDL_GetCPUName()
{
static char SDL_CPUName[48];
if (!SDL_CPUName[0]) {
int i = 0;
int a, b, c, d;
if (CPU_haveCPUID()) {
cpuid(0x80000000, a, b, c, d);
if (a >= 0x80000004) {
cpuid(0x80000002, a, b, c, d);
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
cpuid(0x80000003, a, b, c, d);
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
cpuid(0x80000004, a, b, c, d);
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
}
}
if (!SDL_CPUName[0]) {
SDL_strlcpy(SDL_CPUName, "Unknown", sizeof(SDL_CPUName));
}
}
return SDL_CPUName;
}
static int
SDL_GetCPUCacheLineSize()
{
const char *cpuType = SDL_GetCPUType();
if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
int a, b, c, d;
cpuid(0x00000001, a, b, c, d);
return (((b >> 8) & 0xff) * 8);
} else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
int a, b, c, d;
cpuid(0x80000005, a, b, c, d);
return (c & 0xff);
} else {
/* Just make a guess here... */
return SDL_CACHELINE_SIZE;
}
}
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF; static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
static Uint32 static Uint32
...@@ -521,7 +573,9 @@ int ...@@ -521,7 +573,9 @@ int
main() main()
{ {
printf("CPU count: %d\n", SDL_GetCPUCount()); printf("CPU count: %d\n", SDL_GetCPUCount());
printf("CPU name: %s\n", SDL_GetCPUType()); printf("CPU type: %s\n", SDL_GetCPUType());
printf("CPU name: %s\n", SDL_GetCPUName());
printf("CacheLine size: %d\n", SDL_GetCPUCacheLineSize());
printf("RDTSC: %d\n", SDL_HasRDTSC()); printf("RDTSC: %d\n", SDL_HasRDTSC());
printf("MMX: %d\n", SDL_HasMMX()); printf("MMX: %d\n", SDL_HasMMX());
printf("MMXExt: %d\n", SDL_HasMMXExt()); printf("MMXExt: %d\n", SDL_HasMMXExt());
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "SDL_timer.h" #include "SDL_timer.h"
#include "SDL_timer_c.h" #include "SDL_timer_c.h"
#include "SDL_atomic.h" #include "SDL_atomic.h"
#include "SDL_cpuinfo.h"
#include "SDL_thread.h" #include "SDL_thread.h"
/* #define DEBUG_TIMERS */ /* #define DEBUG_TIMERS */
...@@ -46,9 +47,6 @@ typedef struct _SDL_TimerMap ...@@ -46,9 +47,6 @@ typedef struct _SDL_TimerMap
struct _SDL_TimerMap *next; struct _SDL_TimerMap *next;
} SDL_TimerMap; } SDL_TimerMap;
/* A reasonable guess */
#define CACHELINE_SIZE 128
/* The timers are kept in a sorted list */ /* The timers are kept in a sorted list */
typedef struct { typedef struct {
/* Data used by the main thread */ /* Data used by the main thread */
...@@ -58,7 +56,7 @@ typedef struct { ...@@ -58,7 +56,7 @@ typedef struct {
SDL_mutex *timermap_lock; SDL_mutex *timermap_lock;
/* Padding to separate cache lines between threads */ /* Padding to separate cache lines between threads */
char pad[CACHELINE_SIZE]; char cache_pad[SDL_CACHELINE_SIZE];
/* Data used to communicate with the timer thread */ /* Data used to communicate with the timer thread */
SDL_SpinLock lock; SDL_SpinLock lock;
......
...@@ -243,9 +243,6 @@ void RunEpicTest() ...@@ -243,9 +243,6 @@ void RunEpicTest()
#define NUM_WRITERS 4 #define NUM_WRITERS 4
#define EVENTS_PER_WRITER 1000000 #define EVENTS_PER_WRITER 1000000
/* A decent guess for the size of a cache line on this architecture */
#define CACHELINE 64
/* The number of entries must be a power of 2 */ /* The number of entries must be a power of 2 */
#define MAX_ENTRIES 256 #define MAX_ENTRIES 256
#define WRAP_MASK (MAX_ENTRIES-1) #define WRAP_MASK (MAX_ENTRIES-1)
...@@ -260,22 +257,22 @@ typedef struct ...@@ -260,22 +257,22 @@ typedef struct
{ {
SDL_EventQueueEntry entries[MAX_ENTRIES]; SDL_EventQueueEntry entries[MAX_ENTRIES];
char cache_pad1[CACHELINE-((sizeof(SDL_EventQueueEntry)*MAX_ENTRIES)%CACHELINE)]; char cache_pad1[SDL_CACHELINE_SIZE-((sizeof(SDL_EventQueueEntry)*MAX_ENTRIES)%SDL_CACHELINE_SIZE)];
SDL_atomic_t enqueue_pos; SDL_atomic_t enqueue_pos;
char cache_pad2[CACHELINE-sizeof(SDL_atomic_t)]; char cache_pad2[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)];
SDL_atomic_t dequeue_pos; SDL_atomic_t dequeue_pos;
char cache_pad3[CACHELINE-sizeof(SDL_atomic_t)]; char cache_pad3[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)];
#ifdef TEST_SPINLOCK_FIFO #ifdef TEST_SPINLOCK_FIFO
SDL_SpinLock lock; SDL_SpinLock lock;
SDL_atomic_t rwcount; SDL_atomic_t rwcount;
SDL_atomic_t watcher; SDL_atomic_t watcher;
char cache_pad4[CACHELINE-sizeof(SDL_SpinLock)-2*sizeof(SDL_atomic_t)]; char cache_pad4[SDL_CACHELINE_SIZE-sizeof(SDL_SpinLock)-2*sizeof(SDL_atomic_t)];
#endif #endif
volatile SDL_bool active; volatile SDL_bool active;
...@@ -470,10 +467,10 @@ typedef struct ...@@ -470,10 +467,10 @@ typedef struct
{ {
SDL_EventQueue *queue; SDL_EventQueue *queue;
int index; int index;
char padding1[CACHELINE-(sizeof(SDL_EventQueue*)+sizeof(int))%CACHELINE]; char padding1[SDL_CACHELINE_SIZE-(sizeof(SDL_EventQueue*)+sizeof(int))%SDL_CACHELINE_SIZE];
int waits; int waits;
SDL_bool lock_free; SDL_bool lock_free;
char padding2[CACHELINE-sizeof(int)-sizeof(SDL_bool)]; char padding2[SDL_CACHELINE_SIZE-sizeof(int)-sizeof(SDL_bool)];
} WriterData; } WriterData;
typedef struct typedef struct
...@@ -482,7 +479,7 @@ typedef struct ...@@ -482,7 +479,7 @@ typedef struct
int counters[NUM_WRITERS]; int counters[NUM_WRITERS];
int waits; int waits;
SDL_bool lock_free; SDL_bool lock_free;
char padding[CACHELINE-(sizeof(SDL_EventQueue*)+sizeof(int)*NUM_WRITERS+sizeof(int)+sizeof(SDL_bool))%CACHELINE]; char padding[SDL_CACHELINE_SIZE-(sizeof(SDL_EventQueue*)+sizeof(int)*NUM_WRITERS+sizeof(int)+sizeof(SDL_bool))%SDL_CACHELINE_SIZE];
} ReaderData; } ReaderData;
static int FIFO_Writer(void* _data) static int FIFO_Writer(void* _data)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment