From patchwork Mon Jul 13 11:15:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Huber X-Patchwork-Id: 494512 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A3D381402D9 for ; Mon, 13 Jul 2015 21:16:01 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ETmpxgcf; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=AvxbXo+pS0RN ZlyzOcAAy0LsY9MC6DuuUmixJGE+XP8S2tUBwEox2F+BS5F+asIImSP/O4/TUwlI u7WJO/lFy6reJNcqj6P9lkjHBICR7L9lhDqEmIA6Zv2kNTutmnbcKEMqZ4zkeUPy 8jPyXoXfq8mKqL2XIYpDMn1v5YX1iZE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=roAgTfAwZBTEycxMhC VkgzAIBig=; b=ETmpxgcffW6J6GMDyC4q1Secj51wm2u+BcNoc/vgFwkaiaSejw 6sttDQMUDMdJ6ql9/Q0S42aZud8caFLY7NFmHzLPQUD4GV+IdG0Ca0QWiXio9mBR 8+JFIqHJ2tapR6ZGYwujMI0386kWntfrq0pDL9Ey41oNh45R7lcrUdFo4= Received: (qmail 39067 invoked by alias); 13 Jul 2015 11:15:54 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 39058 invoked by uid 89); 13 Jul 2015 11:15:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.9 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RDNS_DYNAMIC autolearn=no version=3.3.2 X-HELO: mail.embedded-brains.de Received: from host-82-135-62-35.customer.m-online.net (HELO mail.embedded-brains.de) (82.135.62.35) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 13 Jul 2015 11:15:51 +0000 Received: from localhost (localhost.localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id 332152A19B3 for ; Mon, 13 Jul 2015 13:16:24 +0200 (CEST) Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id RJmeMZrfwt_C; Mon, 13 Jul 2015 13:16:21 +0200 (CEST) Received: from localhost (localhost.localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id BE3EB2A19B0; Mon, 13 Jul 2015 13:16:21 +0200 (CEST) Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id akpiiUzYXYfI; Mon, 13 Jul 2015 13:16:21 +0200 (CEST) Received: from huber-linux.eb.localhost (unknown [192.168.96.129]) by mail.embedded-brains.de (Postfix) with ESMTP id 9FD042A1976; Mon, 13 Jul 2015 13:16:21 +0200 (CEST) From: Sebastian Huber To: gcc-patches@gcc.gnu.org Cc: Sebastian Huber Subject: [PATCH] [gomp] Recycle non-nested team if possible Date: Mon, 13 Jul 2015 13:15:44 +0200 Message-Id: <1436786144-8625-1-git-send-email-sebastian.huber@embedded-brains.de> X-IsSubscribed: yes Try to recycle the last non-nested team to avoid the use of malloc() and free() in the normal case where the number of threads is the same. Avoid superfluous destruction and initialization of team synchronization objects. Using the microbenchmark posted here https://gcc.gnu.org/ml/gcc-patches/2008-03/msg00930.html shows an improvement in the parallel bench test case (target x86_64-unknown-linux-gnu, median out of 9 test runs, iteration count increased to 200000). Before the patch: parallel bench 11.2284 seconds After the patch: parallel bench 10.5912 seconds libgomp/ChangeLog 2015-07-13 Sebastian Huber * team.c (get_recycable_team): New. (gomp_new_team): Recycle last non-nested team if possible. (free_team): Destroy more team synchronization objects. (gomp_team_end): Move some team synchronization object destructions to free_team(). --- libgomp/team.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/libgomp/team.c b/libgomp/team.c index b98b233..0bcbaf8 100644 --- a/libgomp/team.c +++ b/libgomp/team.c @@ -134,6 +134,25 @@ gomp_thread_start (void *xdata) return NULL; } +static struct gomp_team * +get_recycable_team (unsigned nthreads) +{ + struct gomp_thread *thr = gomp_thread (); + if (thr->ts.team == NULL) + { + struct gomp_thread_pool *pool = thr->thread_pool; + if (pool != NULL) + { + struct gomp_team *last_team = pool->last_team; + if (last_team != NULL && last_team->nthreads == nthreads) + { + pool->last_team = NULL; + return last_team; + } + } + } + return NULL; +} /* Create a new team data structure. */ @@ -141,18 +160,28 @@ struct gomp_team * gomp_new_team (unsigned nthreads) { struct gomp_team *team; - size_t size; int i; - size = sizeof (*team) + nthreads * (sizeof (team->ordered_release[0]) - + sizeof (team->implicit_task[0])); - team = gomp_malloc (size); + team = get_recycable_team (nthreads); + if (team == NULL) + { + size_t extra = sizeof (team->ordered_release[0]) + + sizeof (team->implicit_task[0]); + team = gomp_malloc (sizeof (*team) + nthreads * extra); + +#ifndef HAVE_SYNC_BUILTINS + gomp_mutex_init (&team->work_share_list_free_lock); +#endif + gomp_barrier_init (&team->barrier, nthreads); + gomp_sem_init (&team->master_release, 0); + gomp_mutex_init (&team->task_lock); + + team->nthreads = nthreads; + } team->work_share_chunk = 8; #ifdef HAVE_SYNC_BUILTINS team->single_count = 0; -#else - gomp_mutex_init (&team->work_share_list_free_lock); #endif team->work_shares_to_free = &team->work_shares[0]; gomp_init_work_share (&team->work_shares[0], false, nthreads); @@ -163,14 +192,9 @@ gomp_new_team (unsigned nthreads) team->work_shares[i].next_free = &team->work_shares[i + 1]; team->work_shares[i].next_free = NULL; - team->nthreads = nthreads; - gomp_barrier_init (&team->barrier, nthreads); - - gomp_sem_init (&team->master_release, 0); team->ordered_release = (void *) &team->implicit_task[nthreads]; team->ordered_release[0] = &team->master_release; - gomp_mutex_init (&team->task_lock); team->task_queue = NULL; team->task_count = 0; team->task_queued_count = 0; @@ -187,6 +211,10 @@ gomp_new_team (unsigned nthreads) static void free_team (struct gomp_team *team) { + gomp_sem_destroy (&team->master_release); +#ifndef HAVE_SYNC_BUILTINS + gomp_mutex_destroy (&team->work_share_list_free_lock); +#endif gomp_barrier_destroy (&team->barrier); gomp_mutex_destroy (&team->task_lock); free (team); @@ -894,10 +922,6 @@ gomp_team_end (void) } while (ws != NULL); } - gomp_sem_destroy (&team->master_release); -#ifndef HAVE_SYNC_BUILTINS - gomp_mutex_destroy (&team->work_share_list_free_lock); -#endif if (__builtin_expect (thr->ts.team != NULL, 0) || __builtin_expect (team->nthreads == 1, 0))