Simple #define for cache line size
Robert Watson
rwatson at FreeBSD.org
Sat Apr 11 09:11:56 PDT 2009
Dear all:
We have a number of __aligned() qualifiers scattered around the kernel
intended to space objects to improve alignment with respect to cache lines.
This is important for a number of reasons, not least avoiding cache line
thrashing when using arrays of foo[MAXCPU]. What I'd like to do is provide a
single compile-time constant, CACHE_LINE_SIZE, defined in machine-dependent
param.h, to use for spacing such objects, rather than hard-coding various
values around. Here are some examples of existing spacing attempts:
i386/include/pcpu.h, line 67
66 #define PCPU_MD_FIELDS \
> 67 char pc_monitorbuf[128] __aligned(128); /* cache line */ \
68 struct pcpu *pc_prvspace; /* Self-reference */ \
kern/sched_ule.c, line 230
229 #endif
> 230 } __aligned(64);
231
vm/uma_core.c, line 115
114 /* The boot-time adjusted value for cache line alignment. */
> 115 static int uma_align_cache = 64 - 1;
116
We could then deploy __aligned(CACHE_LINE_SIZE) in various places, such as on
the description of per-CPU caches for UMA, to ensure that, for example,
per-CPU stats for one CPU weren't in the same cache line as stats for other
CPUs.
NetBSD, FYI, defines CACHE_LINE_SIZE as a global constant in param.h, but I'm
going with an MD definition as I suspect people will want to do different
things on different architectures (and there is variation). I've defaulted
all architectures to 64 bytes, but I suspect a number would prefer to use 32.
Patch below. There's undoubtably an argument for doing something more optimal
than what I'm proposing here, but right now I'm just looking for something
that works, and would be happy to see it replaced with something more mature
once it's available.
Robert N M Watson
Computer Laboratory
University of Cambridge
Index: arm/include/param.h
===================================================================
--- arm/include/param.h (revision 190941)
+++ arm/include/param.h (working copy)
@@ -81,6 +81,10 @@
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT) /* Page size */
#define PAGE_MASK (PAGE_SIZE - 1)
Index: powerpc/include/param.h
===================================================================
--- powerpc/include/param.h (revision 190941)
+++ powerpc/include/param.h (working copy)
@@ -79,6 +79,10 @@
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT) /* Page size */
#define PAGE_MASK (PAGE_SIZE - 1)
Index: sparc64/include/param.h
===================================================================
--- sparc64/include/param.h (revision 190941)
+++ sparc64/include/param.h (working copy)
@@ -71,6 +71,10 @@
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#define PAGE_SHIFT_8K 13
#define PAGE_SIZE_8K (1L<<PAGE_SHIFT_8K)
#define PAGE_MASK_8K (PAGE_SIZE_8K-1)
Index: ia64/include/param.h
===================================================================
--- ia64/include/param.h (revision 190941)
+++ ia64/include/param.h (working copy)
@@ -99,6 +99,10 @@
#define ALIGN(p) _ALIGN(p)
#define ALIGNED_POINTER(p,t) _ALIGNED_POINTER(p,t)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#ifndef LOG2_PAGE_SIZE
#define LOG2_PAGE_SIZE 13 /* 8K pages by default. */
#endif
Index: mips/include/param.h
===================================================================
--- mips/include/param.h (revision 190941)
+++ mips/include/param.h (working copy)
@@ -89,6 +89,10 @@
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#define NBPG 4096 /* bytes/page */
#define PGOFSET (NBPG-1) /* byte offset into page */
#define PGSHIFT 12 /* LOG2(NBPG) */
Index: sun4v/include/param.h
===================================================================
--- sun4v/include/param.h (revision 190941)
+++ sun4v/include/param.h (working copy)
@@ -71,6 +71,10 @@
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#define PAGE_SHIFT_8K 13
#define PAGE_SIZE_8K (1L<<PAGE_SHIFT_8K)
#define PAGE_MASK_8K (PAGE_SIZE_8K-1)
Index: i386/include/param.h
===================================================================
--- i386/include/param.h (revision 190941)
+++ i386/include/param.h (working copy)
@@ -74,6 +74,10 @@
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */
#define PAGE_SIZE (1<<PAGE_SHIFT) /* bytes/page */
#define PAGE_MASK (PAGE_SIZE-1)
Index: amd64/include/param.h
===================================================================
--- amd64/include/param.h (revision 190941)
+++ amd64/include/param.h (working copy)
@@ -89,6 +89,9 @@
#define ALIGN(p) _ALIGN(p)
#define ALIGNED_POINTER(p,t) _ALIGNED_POINTER(p,t)
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
/* Size of the level 1 page table units */
#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
More information about the freebsd-arch
mailing list