Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Apr 2009 17:11:55 +0100 (BST)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        arch@FreeBSD.org
Subject:   Simple #define for cache line size
Message-ID:  <alpine.BSF.2.00.0904111700241.19879@fledge.watson.org>

next in thread | raw e-mail | index | archive | help

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)))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?alpine.BSF.2.00.0904111700241.19879>