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.
This commit is contained in:
parent
1d518f0d73
commit
fb824f9a04
4 changed files with 121 additions and 67 deletions
|
@ -39,6 +39,11 @@ extern "C" {
|
|||
/* *INDENT-ON* */
|
||||
#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.
|
||||
*/
|
||||
|
|
|
@ -337,73 +337,125 @@ SDL_GetCPUCount()
|
|||
static const char *
|
||||
SDL_GetCPUType()
|
||||
{
|
||||
static char SDL_CPUType[48];
|
||||
static char SDL_CPUType[13];
|
||||
|
||||
if (!SDL_CPUType[0]) {
|
||||
int i = 0;
|
||||
int a, b, c, d;
|
||||
|
||||
if (CPU_haveCPUID()) {
|
||||
cpuid(0x00000000, a, b, c, d);
|
||||
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)(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)(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;
|
||||
}
|
||||
if (!SDL_CPUType[0]) {
|
||||
SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(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_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;
|
||||
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_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;
|
||||
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_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;
|
||||
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_CPUType[0]) {
|
||||
SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType));
|
||||
if (!SDL_CPUName[0]) {
|
||||
SDL_strlcpy(SDL_CPUName, "Unknown", sizeof(SDL_CPUName));
|
||||
}
|
||||
}
|
||||
return SDL_CPUType;
|
||||
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;
|
||||
|
@ -521,7 +573,9 @@ int
|
|||
main()
|
||||
{
|
||||
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("MMX: %d\n", SDL_HasMMX());
|
||||
printf("MMXExt: %d\n", SDL_HasMMXExt());
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "SDL_timer.h"
|
||||
#include "SDL_timer_c.h"
|
||||
#include "SDL_atomic.h"
|
||||
#include "SDL_cpuinfo.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
/* #define DEBUG_TIMERS */
|
||||
|
@ -46,9 +47,6 @@ typedef struct _SDL_TimerMap
|
|||
struct _SDL_TimerMap *next;
|
||||
} SDL_TimerMap;
|
||||
|
||||
/* A reasonable guess */
|
||||
#define CACHELINE_SIZE 128
|
||||
|
||||
/* The timers are kept in a sorted list */
|
||||
typedef struct {
|
||||
/* Data used by the main thread */
|
||||
|
@ -58,7 +56,7 @@ typedef struct {
|
|||
SDL_mutex *timermap_lock;
|
||||
|
||||
/* 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 */
|
||||
SDL_SpinLock lock;
|
||||
|
|
|
@ -243,9 +243,6 @@ void RunEpicTest()
|
|||
#define NUM_WRITERS 4
|
||||
#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 */
|
||||
#define MAX_ENTRIES 256
|
||||
#define WRAP_MASK (MAX_ENTRIES-1)
|
||||
|
@ -260,22 +257,22 @@ typedef struct
|
|||
{
|
||||
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;
|
||||
|
||||
char cache_pad2[CACHELINE-sizeof(SDL_atomic_t)];
|
||||
char cache_pad2[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)];
|
||||
|
||||
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
|
||||
SDL_SpinLock lock;
|
||||
SDL_atomic_t rwcount;
|
||||
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
|
||||
|
||||
volatile SDL_bool active;
|
||||
|
@ -470,10 +467,10 @@ typedef struct
|
|||
{
|
||||
SDL_EventQueue *queue;
|
||||
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;
|
||||
SDL_bool lock_free;
|
||||
char padding2[CACHELINE-sizeof(int)-sizeof(SDL_bool)];
|
||||
char padding2[SDL_CACHELINE_SIZE-sizeof(int)-sizeof(SDL_bool)];
|
||||
} WriterData;
|
||||
|
||||
typedef struct
|
||||
|
@ -482,7 +479,7 @@ typedef struct
|
|||
int counters[NUM_WRITERS];
|
||||
int waits;
|
||||
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;
|
||||
|
||||
static int FIFO_Writer(void* _data)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue