From nobody Sun Aug 2 15:04:14 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hCjl35cnBz6nh18; Sun, 02 Aug 2026 15:04:31 +0000 (UTC) (envelope-from kib@freebsd.org) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4hCjl31MLzz447y; Sun, 02 Aug 2026 15:04:31 +0000 (UTC) (envelope-from kib@freebsd.org) Authentication-Results: mx1.freebsd.org; none Received: from tom.home (kib@localhost [127.0.0.1] (may be forged)) by kib.kiev.ua (8.18.1/8.18.1) with ESMTP id 672F4FsH029686; Sun, 2 Aug 2026 18:04:18 +0300 (EEST) (envelope-from kib@freebsd.org) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua 672F4FsH029686 Received: (from kostik@localhost) by tom.home (8.18.1/8.18.1/Submit) id 672F4E0q029685; Sun, 2 Aug 2026 18:04:14 +0300 (EEST) (envelope-from kib@freebsd.org) X-Authentication-Warning: tom.home: kostik set sender to kib@freebsd.org using -f Date: Sun, 2 Aug 2026 18:04:14 +0300 From: Konstantin Belousov To: Robert Clausecker Cc: src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org, Minsoo Choo Subject: Re: git: 00a79975c062 - main - libc/merge.c: use memcpy() for copying Message-ID: References: <6a6f33ca.1f0f3.c2ca741@gitrepo.freebsd.org> List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <6a6f33ca.1f0f3.c2ca741@gitrepo.freebsd.org> X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=4.0.2 X-Spam-Checker-Version: SpamAssassin 4.0.2 (2025-08-27) on tom.home X-Rspamd-Queue-Id: 4hCjl31MLzz447y X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:6939, ipnet:2001:470::/32, country:US] X-Spamd-Bar: ---- On Sun, Aug 02, 2026 at 12:10:50PM +0000, Robert Clausecker wrote: > The branch main has been updated by fuz: > > URL: https://cgit.FreeBSD.org/src/commit/?id=00a79975c062650ba15e432e30776d42fc44fbaa > > commit 00a79975c062650ba15e432e30776d42fc44fbaa > Author: Minsoo Choo > AuthorDate: 2026-07-02 19:47:33 +0000 > Commit: Robert Clausecker > CommitDate: 2026-08-02 11:17:45 +0000 > > libc/merge.c: use memcpy() for copying > > Currently mergesort() uses ICOPY_*() to copy data as four byte blocks > instead of one byte. However, this is only achievable when both size and > base arguments are aligned to four bytes. > > Use of memcpy() is ideal as 1) it is cleaner and 2) the library will use > SIMD for copying when the hardware supports it. Compared to ICOPY_*(), > SIMD can support up to 64 bytes. When the SIMD-backed memcpy() find the > address is unaligned, it can first copy data up to the nearest aligned > address, and then use SIMD operations for faster transfer. Thus memcpy() > can give better performance than mergesort()'s own implementation. > > This is benchmarked on amd64 where there isn't a SIMD-backed > implementation yet. However, the baseline implementation in assembly > already delivers better performance in unaligned cases although there is > some performance drops in aligned cases. The benchmark results and > script is available in the Phabricator review. Ideally, more performance > improvements will come when amd64 gets SIMD implementation of memcpy(). > > Signed-off-by: Minsoo Choo > Reviewed by: fuz > MFC after: 1 week > Differential Revision: https://reviews.freebsd.org/D58002 > --- > lib/libc/stdlib/merge.c | 69 +++++++++++++++---------------------------------- > 1 file changed, 21 insertions(+), 48 deletions(-) > > diff --git a/lib/libc/stdlib/merge.c b/lib/libc/stdlib/merge.c > index e07a3947e741..7c15fa7953f9 100644 > --- a/lib/libc/stdlib/merge.c > +++ b/lib/libc/stdlib/merge.c > @@ -66,25 +66,19 @@ typedef int (*cmp_t)(const void *, const void *); > static void setup(u_char *, u_char *, size_t, size_t, cmp_t); > static void insertionsort(u_char *, size_t, size_t, cmp_t); > > -#define ISIZE sizeof(int) > #define PSIZE sizeof(u_char *) > -#define ICOPY_LIST(src, dst, last) \ > - do \ > - *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \ > - while(src < last) > -#define ICOPY_ELT(src, dst, i) \ > - do \ > - *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \ > - while (i -= ISIZE) > - > -#define CCOPY_LIST(src, dst, last) \ > - do \ > - *dst++ = *src++; \ > - while (src < last) > -#define CCOPY_ELT(src, dst, i) \ > - do \ > - *dst++ = *src++; \ > - while (i -= 1) > +#define COPY_LIST(src, dst, last) \ > + do { \ > + memcpy(dst, src, last - src); \ > + dst += last - src; \ > + src += last - src; \ > + } while (0) > +#define COPY_ELT(src, dst, i) \ > + do { \ > + memcpy(dst, src, i); \ > + src += i; \ > + dst += i; \ > + } while (0) > > /* > * Find the next possible pointer head. (Trickery for forcing an array > @@ -112,7 +106,7 @@ mergesort(void *base, size_t nmemb, size_t size, cmp_t cmp) > { > size_t i, nbytes, asize; > int sense; > - int big, iflag; > + int big; > u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; > u_char *list2, *list1, *p2, *p, *last, **p1; > > @@ -129,10 +123,6 @@ mergesort(void *base, size_t nmemb, size_t size, cmp_t cmp) > return (-1); > } > > - iflag = 0; > - if (__is_aligned(size, ISIZE) && __is_aligned(base, ISIZE)) > - iflag = 1; > - > if ((list2 = malloc(asize)) == NULL) > return (-1); > > @@ -200,34 +190,17 @@ COPY: b = t; > } > i = size; > if (q == f1) { > - if (iflag) { > - ICOPY_LIST(f2, tp2, b); > - ICOPY_ELT(f1, tp2, i); > - } else { > - CCOPY_LIST(f2, tp2, b); > - CCOPY_ELT(f1, tp2, i); > - } > + COPY_LIST(f2, tp2, b); > + COPY_ELT(f1, tp2, i); > } else { > - if (iflag) { > - ICOPY_LIST(f1, tp2, b); > - ICOPY_ELT(f2, tp2, i); > - } else { > - CCOPY_LIST(f1, tp2, b); > - CCOPY_ELT(f2, tp2, i); > - } > + COPY_LIST(f1, tp2, b); > + COPY_ELT(f2, tp2, i); The spacing is inconsistent, it is partially spaces, partially tabs, for all additions of COPY_XXX() lines. > } > } > - if (f2 < l2) { > - if (iflag) > - ICOPY_LIST(f2, tp2, l2); > - else > - CCOPY_LIST(f2, tp2, l2); > - } else if (f1 < l1) { > - if (iflag) > - ICOPY_LIST(f1, tp2, l1); > - else > - CCOPY_LIST(f1, tp2, l1); > - } > + if (f2 < l2) > + COPY_LIST(f2, tp2, l2); > + else if (f1 < l1) > + COPY_LIST(f1, tp2, l1); > *p1 = l2; > } > tp2 = list1; /* swap list1, list2 */