From owner-freebsd-arch@FreeBSD.ORG Sat Apr 11 16:11:56 2009 Return-Path: Delivered-To: arch@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2C8411065670 for ; Sat, 11 Apr 2009 16:11:56 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id E08978FC0A for ; Sat, 11 Apr 2009 16:11:55 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from fledge.watson.org (fledge.watson.org [65.122.17.41]) by cyrus.watson.org (Postfix) with ESMTPS id 79FDF46B06 for ; Sat, 11 Apr 2009 12:11:55 -0400 (EDT) Date: Sat, 11 Apr 2009 17:11:55 +0100 (BST) From: Robert Watson X-X-Sender: robert@fledge.watson.org To: arch@FreeBSD.org Message-ID: User-Agent: Alpine 2.00 (BSF 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; format=flowed; charset=US-ASCII Cc: Subject: Simple #define for cache line size X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Apr 2009 16:11:56 -0000 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<