From patchwork Wed Oct 6 18:05:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 45939 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 518B43858003 for ; Wed, 6 Oct 2021 18:18:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 518B43858003 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1633544330; bh=j6bjTOW5sxPcREQG79wL8rdjsmwAHLReH1LfYm93780=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=rX7sBHvTtpJ6sHLxgmr9s9p0oXqEq5VUnzEuCzraoSgX2UqO0kKdvk2PnHaQ+WnmZ zJOi8UWMecTS/Q+W9JwBjhQRggEUgGJI7OZO2OXub68nqllf/DLdd4XO59k333ZHsg wl67Z6/IJ3eCJ+ingGip6H0Uwrb6psoIzZxCGAq4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qv1-xf2b.google.com (mail-qv1-xf2b.google.com [IPv6:2607:f8b0:4864:20::f2b]) by sourceware.org (Postfix) with ESMTPS id 1B70F3858410 for ; Wed, 6 Oct 2021 18:15:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1B70F3858410 Received: by mail-qv1-xf2b.google.com with SMTP id o13so2508641qvm.4 for ; Wed, 06 Oct 2021 11:15:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=j6bjTOW5sxPcREQG79wL8rdjsmwAHLReH1LfYm93780=; b=easV8wlOSZBewOBUUM4SBrU1i+epVUL0ArZ5yaQelWsUX1Mk5H//GJx4hzg/g5oRPW Adf2NRCVEe/3NIJfImYSIYff+FxGSnvyeavJedCMImMZxoBVku+flkMKMrcLHmUDSpRW d2Zi/9/N54l4QNKCGW3+OHSICILo/l6SkPZrOZ1O/3+VwkKuebmW1eD7QdWI6MEwOGVM bMV+3dgxzPa2yJTEo5SzRCzU4KSOflPlJ669RLxhAe0zi8U9Qq+0V68JBbYJI6/4zp3d EpKTZX/gqEf9LX6ujo2uxXN7j+lN1w5Ph4dytwzKgbO4xx6CxgJdUGKWu1WuJwsFUQe1 enqA== X-Gm-Message-State: AOAM53342r4Pme01hc/nC0MvIjUoXVH+tHbWnEyJMRywx0lniWAMzqav ByhE4fdhobKoYbb2dXDGz/qaFoWUv+Qg+g== X-Google-Smtp-Source: ABdhPJxESu41BfQR9kgVS/7avkvn1o/yCIhGr8p+asi/fsipzh/J2DsnjsBTSZZmluLYE/dknna0Ng== X-Received: by 2002:a0c:e08c:: with SMTP id l12mr7537711qvk.67.1633544136499; Wed, 06 Oct 2021 11:15:36 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:807a:2ebe:4b13:27bd:f11d]) by smtp.gmail.com with ESMTPSA id 18sm14161168qtz.49.2021.10.06.11.15.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Oct 2021 11:15:36 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH 8/9] i386: Move hypot implementation to C Date: Wed, 6 Oct 2021 15:05:56 -0300 Message-Id: <20211006180557.933826-9-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211006180557.933826-1-adhemerval.zanella@linaro.org> References: <20211006180557.933826-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The generic hypotf is slight slower, mostly due the tricks the assembly does to optimize the isinf/isnan/issignaling. Results on a Ryzen 5900X with gcc 10.3.1: master: "hypotf": { "workload-random": { "duration": 3.76493e+09, "iterations": 6.8e+07, "reciprocal-throughput": 38.4243, "latency": 72.309, "max-throughput": 2.60252e+07, "min-throughput": 1.38295e+07 } } patched: "hypotf": { "workload-random": { "duration": 3.78098e+09, "iterations": 6.8e+07, "reciprocal-throughput": 28.9206, "latency": 82.2848, "max-throughput": 3.45774e+07, "min-throughput": 1.21529e+07 } } The generic hypot is way slower, since the optimized implementation uses the i386 default excessive precision to issue the operation directly. A similar implementation is provided instead of using the generic implementation: master: "hypot": { "workload-random": { "duration": 3.7452e+09, "iterations": 6.6e+07, "reciprocal-throughput": 40.3203, "latency": 73.1707, "max-throughput": 2.48014e+07, "min-throughput": 1.36667e+07 } } patched: ./benchtests/bench-hypot "hypot": { "workload-random": { "duration": 3.72606e+09, "iterations": 7.6e+07, "reciprocal-throughput": 25.9437, "latency": 72.1104, "max-throughput": 3.8545e+07, "min-throughput": 1.38676e+07 } } Checked on i686-linux-gnu. --- sysdeps/i386/fpu/e_hypot.S | 75 ------------------------------------- sysdeps/i386/fpu/e_hypot.c | 42 +++++++++++++++++++++ sysdeps/i386/fpu/e_hypotf.S | 64 ------------------------------- 3 files changed, 42 insertions(+), 139 deletions(-) delete mode 100644 sysdeps/i386/fpu/e_hypot.S create mode 100644 sysdeps/i386/fpu/e_hypot.c delete mode 100644 sysdeps/i386/fpu/e_hypotf.S diff --git a/sysdeps/i386/fpu/e_hypot.S b/sysdeps/i386/fpu/e_hypot.S deleted file mode 100644 index f2c956b77a..0000000000 --- a/sysdeps/i386/fpu/e_hypot.S +++ /dev/null @@ -1,75 +0,0 @@ -/* Compute the hypothenuse of X and Y. - Copyright (C) 1998-2021 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 - . */ - -#include -#include -#include - -DEFINE_DBL_MIN - -#ifdef PIC -# define MO(op) op##@GOTOFF(%edx) -#else -# define MO(op) op -#endif - - .text -ENTRY(__ieee754_hypot) -#ifdef PIC - LOAD_PIC_REG (dx) -#endif - fldl 4(%esp) // x - fxam - fnstsw - fldl 12(%esp) // y : x - movb %ah, %ch - fxam - fnstsw - movb %ah, %al - orb %ch, %ah - sahf - jc 1f - fmul %st(0) // y * y : x - fxch // x : y * y - fmul %st(0) // x * x : y * y - faddp // x * x + y * y - fsqrt - DBL_NARROW_EVAL_UFLOW_NONNEG -2: ret - - // We have to test whether any of the parameters is Inf. - // In this case the result is infinity. -1: andb $0x45, %al - cmpb $5, %al - je 3f // jump if y is Inf - andb $0x45, %ch - cmpb $5, %ch - jne 4f // jump if x is not Inf - fxch -3: fstp %st(1) - fabs - jmp 2b - -4: testb $1, %al - jnz 5f // y is NaN - fxch -5: fstp %st(1) - jmp 2b - -END(__ieee754_hypot) -libm_alias_finite (__ieee754_hypot, __hypot) diff --git a/sysdeps/i386/fpu/e_hypot.c b/sysdeps/i386/fpu/e_hypot.c new file mode 100644 index 0000000000..4920a8cb49 --- /dev/null +++ b/sysdeps/i386/fpu/e_hypot.c @@ -0,0 +1,42 @@ +/* Euclidean distance function. Double/Binary64 i386 version. + Copyright (C) 2021 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 + . */ + +#include +#include +#include +#include +#include +#include + +/* The i386 allows ot use the default excess of precision to optimize the + hypot implementation, since internal multiplication and sqrt is carried + with 80-bit FP type. */ +double +__ieee754_hypot (double x, double y) +{ + if ((isinf (x) || isinf (y)) + && !issignaling (x) && !issignaling (y)) + return INFINITY; + if (isnan (x) || isnan (y)) + return x + y; + + double r = math_narrow_eval (sqrt (x * x + y * y)); + math_check_force_underflow_nonneg (r); + return r; +} +libm_alias_finite (__ieee754_hypot, __hypot) diff --git a/sysdeps/i386/fpu/e_hypotf.S b/sysdeps/i386/fpu/e_hypotf.S deleted file mode 100644 index cec5d15403..0000000000 --- a/sysdeps/i386/fpu/e_hypotf.S +++ /dev/null @@ -1,64 +0,0 @@ -/* Compute the hypothenuse of X and Y. - Copyright (C) 1998-2021 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 - . */ - -#include -#include -#include - - .text -ENTRY(__ieee754_hypotf) - flds 4(%esp) // x - fxam - fnstsw - flds 8(%esp) // y : x - movb %ah, %ch - fxam - fnstsw - movb %ah, %al - orb %ch, %ah - sahf - jc 1f - fmul %st(0) // y * y : x - fxch // x : y * y - fmul %st(0) // x * x : y * y - faddp // x * x + y * y - fsqrt - FLT_NARROW_EVAL -2: ret - - // We have to test whether any of the parameters is Inf. - // In this case the result is infinity. -1: andb $0x45, %al - cmpb $5, %al - je 3f // jump if y is Inf - andb $0x45, %ch - cmpb $5, %ch - jne 4f // jump if x is not Inf - fxch -3: fstp %st(1) - fabs - jmp 2b - -4: testb $1, %al - jnz 5f // y is NaN - fxch -5: fstp %st(1) - jmp 2b - -END(__ieee754_hypotf) -libm_alias_finite (__ieee754_hypotf, __hypotf)