diff options
author | adrian <adrian@FreeBSD.org> | 2015-04-27 12:50:20 +0800 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2015-04-27 12:50:20 +0800 |
commit | e7925b34dd92e4e4a5780bafcb092586f426b9d4 (patch) | |
tree | a221277bbc5d4c9a757434fe645fcef16a321e90 /lang | |
parent | 3b27bd8f5e8255b609c0398a025a19a4ec105b6f (diff) | |
download | freebsd-ports-graphics-e7925b34dd92e4e4a5780bafcb092586f426b9d4.tar.gz freebsd-ports-graphics-e7925b34dd92e4e4a5780bafcb092586f426b9d4.tar.zst freebsd-ports-graphics-e7925b34dd92e4e4a5780bafcb092586f426b9d4.zip |
Implement the FreeBSD specific pieces for thread affinity for OpenMP.
Upstream gcc 4.8 doesn't have support for this - it'll create threads,
but it won't do any of the thread affinity stuff for FreeBSD.
This allows for OMP_PROC_BIND=true to bind threads to their initial
CPUs, leading to some pretty drastic improvements in performance
for certain NUMA workloads.
Approved by: gerald
Sponsored by: Norse Corp, Inc.
Diffstat (limited to 'lang')
-rw-r--r-- | lang/gcc48/Makefile | 1 | ||||
-rw-r--r-- | lang/gcc48/files/patch-libgomp-freebsd-affinity | 117 | ||||
-rw-r--r-- | lang/gcc48/files/patch-libgomp-posix-affinity | 18 |
3 files changed, 136 insertions, 0 deletions
diff --git a/lang/gcc48/Makefile b/lang/gcc48/Makefile index 5605336aedc..26ab12791bf 100644 --- a/lang/gcc48/Makefile +++ b/lang/gcc48/Makefile @@ -3,6 +3,7 @@ PORTNAME= gcc PORTVERSION= 4.8.5.s20150402 +PORTREVISION= 1 CATEGORIES= lang java MASTER_SITES= ${MASTER_SITE_GCC} MASTER_SITE_SUBDIR= snapshots/${DISTVERSION} diff --git a/lang/gcc48/files/patch-libgomp-freebsd-affinity b/lang/gcc48/files/patch-libgomp-freebsd-affinity new file mode 100644 index 00000000000..7b35399a66a --- /dev/null +++ b/lang/gcc48/files/patch-libgomp-freebsd-affinity @@ -0,0 +1,117 @@ +--- libgomp/config/bsd/freebsd_affinity.c.orig 2015-04-26 05:29:16.795040000 -0700 ++++ libgomp/config/bsd/freebsd_affinity.c 2015-04-26 05:29:03.462728000 -0700 +@@ -0,0 +1,114 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ Contributed by Adrian Chadd <adrian@FreeBSD.org>. ++ Based on work by Jakub Jelinek <jakub@redhat.com>. ++ ++ This file is part of the GNU OpenMP Library (libgomp). ++ ++ Libgomp is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ++ FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++/* This is a FreeBSD specific implementation of a CPU affinity setting. */ ++ ++#include "libgomp.h" ++ ++#include <stdlib.h> ++#include <unistd.h> ++#include <pthread.h> ++#include <pthread_np.h> ++ ++static unsigned int affinity_counter; ++ ++void ++gomp_init_affinity (void) ++{ ++ cpuset_t cpuset, cpusetnew; ++ size_t idx, widx; ++ unsigned long cpus = 0; ++ ++ if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset)) ++ { ++ gomp_error ("could not get CPU affinity set"); ++ free (gomp_cpu_affinity); ++ gomp_cpu_affinity = NULL; ++ gomp_cpu_affinity_len = 0; ++ return; ++ } ++ ++ CPU_ZERO (&cpusetnew); ++ if (gomp_cpu_affinity_len == 0) ++ { ++ unsigned long count = CPU_COUNT(&cpuset); ++ if (count >= 65536) ++ count = 65536; ++ gomp_cpu_affinity = malloc (count * sizeof (unsigned short)); ++ if (gomp_cpu_affinity == NULL) ++ { ++ gomp_error ("not enough memory to store CPU affinity list"); ++ return; ++ } ++ for (widx = idx = 0; widx < count && idx < 65536; idx++) ++ if (CPU_ISSET (idx, &cpuset)) ++ { ++ cpus++; ++ gomp_cpu_affinity[widx++] = idx; ++ } ++ } ++ else ++ for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++) ++ if (gomp_cpu_affinity[idx] < CPU_SETSIZE ++ && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset)) ++ { ++ if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpusetnew)) ++ { ++ cpus++; ++ CPU_SET (gomp_cpu_affinity[idx], &cpusetnew); ++ } ++ gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx]; ++ } ++ ++ if (widx == 0) ++ { ++ gomp_error ("no CPUs left for affinity setting"); ++ free (gomp_cpu_affinity); ++ gomp_cpu_affinity = NULL; ++ gomp_cpu_affinity_len = 0; ++ return; ++ } ++ ++ gomp_cpu_affinity_len = widx; ++ if (cpus < gomp_available_cpus) ++ gomp_available_cpus = cpus; ++ CPU_ZERO (&cpuset); ++ CPU_SET (gomp_cpu_affinity[0], &cpuset); ++ pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset); ++ affinity_counter = 1; ++} ++ ++void ++gomp_init_thread_affinity (pthread_attr_t *attr) ++{ ++ unsigned int cpu; ++ cpuset_t cpuset; ++ ++ cpu = __atomic_fetch_add (&affinity_counter, 1, MEMMODEL_RELAXED); ++ cpu %= gomp_cpu_affinity_len; ++ CPU_ZERO (&cpuset); ++ CPU_SET (gomp_cpu_affinity[cpu], &cpuset); ++ pthread_attr_setaffinity_np (attr, sizeof (cpuset_t), &cpuset); ++} diff --git a/lang/gcc48/files/patch-libgomp-posix-affinity b/lang/gcc48/files/patch-libgomp-posix-affinity new file mode 100644 index 00000000000..c4ab742f061 --- /dev/null +++ b/lang/gcc48/files/patch-libgomp-posix-affinity @@ -0,0 +1,18 @@ +--- libgomp/config/posix/affinity.c.orig 2015-04-26 05:29:27.925344000 -0700 ++++ libgomp/config/posix/affinity.c 2015-04-26 05:29:44.449277000 -0700 +@@ -26,6 +26,10 @@ + + #include "libgomp.h" + ++#ifdef __FreeBSD__ ++#include "../bsd/freebsd_affinity.c" ++#else ++ + void + gomp_init_affinity (void) + { +@@ -36,3 +40,4 @@ + { + (void) attr; + } ++#endif |