From patchwork Wed May 11 10:23:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wilco Dijkstra X-Patchwork-Id: 12201 Received: (qmail 107397 invoked by alias); 11 May 2016 10:24:14 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 107243 invoked by uid 89); 11 May 2016 10:24:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=bzero, thousand, H*MI:outlook, 2016-05-11 X-HELO: eu-smtp-delivery-143.mimecast.com From: Wilco Dijkstra To: 'GNU C Library' CC: nd Subject: [PATCH] Add random memcpy test Date: Wed, 11 May 2016 10:23:52 +0000 Message-ID: x-ms-office365-filtering-correlation-id: 94ede2f0-7abf-4307-3b04-08d379865974 x-microsoft-exchange-diagnostics: 1; AM3PR08MB0085; 5:roTKxnN0FzdlFhn3PSVjr9Zx7STAyAn4OFuAqP+QnctVWo5zKFoRG1EtBYw6iUVh8nDgB8ZeIwj8qas0VKEuItYp7b2x3Jcj/rZUOy+OXwwQn6Ai5aNg30Jnk8DGSAucZkky0pqmrCaReMbMMGLKzw==; 24:ezByQvoHtdmNzNaHXTbRZaQPPkFJmHqCn1ZMr2ltBMPGQMwzOzOzj05rSCb29OWEZDGJkXmOxD+QlMc5l5S2VT254DMwIvSPjUpLyzWAIgA=; 7:O47S2F8Kn07DHf+Z9+prS57R1tTanUY53s4X2cM0eti59eF+GYIxjS9Q0/HT720DTikRzuys6mq1eIfEyx0LBI8Kr8Mh00MOHAHyKTHOl3b+kUgOS88G98SdBsp5OKQW41HuXJi/9EfTDlEbkopN5AnfEe7GsJrxLpa2WOHdDa0uRHstPJynV41d1QqlHIuL; 20:5rYPKld5iGdnKV7ohLBcFNPibGP1+wlWMSgL34C5NP5Ur2LbKS+RF2kJm5098tFH2gZMYLt6j7yrev51DW1Hfl+Hejlm5swDmEXggqXVFLU27hKxpd4rqtAkdPKo0nzrLgjrI/BNbMcVC+4RiIl4PHtlRsBcsRQqtHO2nlQdJpM= x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM3PR08MB0085; nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026); SRVR:AM3PR08MB0085; BCL:0; PCL:0; RULEID:; SRVR:AM3PR08MB0085; x-forefront-prvs: 0939529DE2 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(6009001)(377424004)(86362001)(575784001)(76576001)(15975445007)(74316001)(189998001)(5008740100001)(4326007)(110136002)(92566002)(11100500001)(50986999)(81166006)(54356999)(5004730100002)(3846002)(6116002)(102836003)(1220700001)(586003)(229853001)(87936001)(8936002)(2900100001)(106116001)(66066001)(5002640100001)(5250100002)(33656002)(9686002)(450100001)(3660700001)(19580395003)(3280700002)(19580405001)(5003600100002)(2906002)(2004002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR08MB0085; H:AM3PR08MB0088.eurprd08.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; spamdiagnosticoutput: 1:23 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-originalarrivaltime: 11 May 2016 10:23:52.1489 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR08MB0085 X-MC-Unique: MEZl-N9mS5Gws_l6U-RlaQ-1 This patch adds a new memcpy test that uses small copy sizes using random alignment and size. The copy size is based on a preset distribution that favors smaller sizes and multiples of 4, 8 and 16. Instead of repeating the same copy over and over again like the existing tests, it times several thousand different copies to more accurately estimate the overhead of branch prediction. OK for commit? ChangeLog: 2016-05-11 Wilco Dijkstra * benchtests/Makefile (string-benchset): Add memcpy-random. * benchtests/bench-memcpy-random.c: New file. diff --git a/benchtests/Makefile b/benchtests/Makefile index 61077ea9b6f7d4c342192429a8d90ecdf9bdaea7..03311dd72856bf0e595a759b817cb772f0fd3a6f 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -38,7 +38,7 @@ string-benchset := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ strcat strchr strchrnul strcmp strcpy strcspn strlen \ strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok \ - strcoll memcpy-large memmove-large memset-large + strcoll memcpy-large memcpy-random memmove-large memset-large wcsmbs-benchset := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ wcscmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn \ wmemchr wmemset wmemcmp diff --git a/benchtests/bench-memcpy-random.c b/benchtests/bench-memcpy-random.c new file mode 100644 index 0000000000000000000000000000000000000000..668d6a1d35074f4227be4e1ff424da556a377cef --- /dev/null +++ b/benchtests/bench-memcpy-random.c @@ -0,0 +1,130 @@ +/* Measure memcpy functions. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define MIN_PAGE_SIZE 131072 +#define TEST_MAIN +#define TEST_NAME "memcpy-random" +#include "bench-string.h" + +IMPL (memcpy, 0) + +#define NUM_COPIES 2048 +#define NUM_DISTR 1024 + +typedef struct +{ + uint16_t src; + uint16_t dst; + uint16_t len; +} copy_t; + +static copy_t copy[NUM_COPIES]; +static uint8_t copy_distribution[NUM_DISTR]; + +typedef char *(*proto_t) (char *, const char *, size_t); + + +static void +init_copy_distribution (void) +{ + int i, n, pos = 0; + for (i = 0; i < 256; i++) + { + if (i < 8) + n = 1; + else if (i < 16) + n = 8; + else if (i < 32) + n = 6; + else if (i < 64) + n = 4; + else if (i < 128) + n = 2; + else + n = 1; + + if ((i & 15) == 0) + n = n * 7; + else if ((i & 7) == 0) + n = n * 5; + else if ((i & 3) == 0) + n = n * 3; + + for ( ; n > 0 && pos < NUM_DISTR; n--) + copy_distribution[pos++] = i; + } + for ( ; pos < NUM_DISTR; pos++) + copy_distribution[pos] = 255; +} + +static void +do_one_test (impl_t *impl, char *dst, char *src, copy_t *copy, size_t n) +{ + timing_t start, stop, cur; + size_t iters = INNER_LOOP_ITERS * 20; + + TIMING_NOW (start); + for (int i = 0; i < iters; ++i) + for (int j = 0; j < n; j++) + CALL (impl, dst + copy[j].dst, src + copy[j].src, copy[j].len); + TIMING_NOW (stop); + + TIMING_DIFF (cur, start, stop); + + TIMING_PRINT_MEAN ((double) cur, (double) iters); +} + +static void +do_test (size_t max_size) +{ + for (int i = 0; i < max_size; i++) + buf1[i] = i * 3; + + for (int i = 0; i < NUM_COPIES; i++) + { + copy[i].dst = rand () & (max_size - 1); + copy[i].src = rand () & (max_size - 1); + copy[i].len = copy_distribution[rand () & (NUM_DISTR - 1)]; + } + + printf ("Memory size %6zd:", max_size); + + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (char *) buf2, (char *) buf1, copy, NUM_COPIES); + + putchar ('\n'); +} + +int +test_main (void) +{ + test_init (); + init_copy_distribution (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) + printf ("\t%s", impl->name); + putchar ('\n'); + + for (int i = 4; i <= 64; i = i * 2) + do_test (i * 1024); + + return ret; +} + +#include "../test-skeleton.c"