changeset 5117:427998ff3bcf

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.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 27 Jan 2011 16:46:15 -0800
parents e337f792c6a7
children 02b860cbc7ce
files include/SDL_cpuinfo.h src/cpuinfo/SDL_cpuinfo.c src/timer/SDL_timer.c test/testatomic.c
diffstat 4 files changed, 121 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/include/SDL_cpuinfo.h	Thu Jan 27 15:31:00 2011 -0800
+++ b/include/SDL_cpuinfo.h	Thu Jan 27 16:46:15 2011 -0800
@@ -39,6 +39,11 @@
 /* *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.
  */
--- a/src/cpuinfo/SDL_cpuinfo.c	Thu Jan 27 15:31:00 2011 -0800
+++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Jan 27 16:46:15 2011 -0800
@@ -337,73 +337,125 @@
 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 @@
 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());
--- a/src/timer/SDL_timer.c	Thu Jan 27 15:31:00 2011 -0800
+++ b/src/timer/SDL_timer.c	Thu Jan 27 16:46:15 2011 -0800
@@ -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 @@
     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 @@
     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;
--- a/test/testatomic.c	Thu Jan 27 15:31:00 2011 -0800
+++ b/test/testatomic.c	Thu Jan 27 16:46:15 2011 -0800
@@ -243,9 +243,6 @@
 #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 @@
 {
     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 @@
 {
     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 @@
     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)