From patchwork Fri Feb 28 02:24:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Hoo X-Patchwork-Id: 11411409 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ECF071580 for ; Fri, 28 Feb 2020 02:26:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD992246A3 for ; Fri, 28 Feb 2020 02:26:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CD992246A3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:40766 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j7VMZ-0007vK-Uf for patchwork-qemu-devel@patchwork.kernel.org; Thu, 27 Feb 2020 21:26:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53916) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j7VM1-00079o-TA for qemu-devel@nongnu.org; Thu, 27 Feb 2020 21:26:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j7VM0-00076E-JB for qemu-devel@nongnu.org; Thu, 27 Feb 2020 21:26:17 -0500 Received: from mga03.intel.com ([134.134.136.65]:21705) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j7VM0-0006Dr-BW for qemu-devel@nongnu.org; Thu, 27 Feb 2020 21:26:16 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2020 18:25:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,493,1574150400"; d="scan'208";a="238622576" Received: from sqa-gate.sh.intel.com (HELO robert-ivt.tsp.org) ([10.239.48.212]) by orsmga003.jf.intel.com with ESMTP; 27 Feb 2020 18:25:10 -0800 From: Robert Hoo To: qemu-devel@nongnu.org, pbonzini@redhat.com, richard.henderson@linaro.org, laurent@vivier.eu, philmd@redhat.com, berrange@redhat.com Subject: [PATCH v3 1/2] configure: add configure option avx512f_opt Date: Fri, 28 Feb 2020 10:24:55 +0800 Message-Id: <1582856696-45663-2-git-send-email-robert.hu@linux.intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1582856696-45663-1-git-send-email-robert.hu@linux.intel.com> References: <1582856696-45663-1-git-send-email-robert.hu@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.65 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: robert.hu@intel.com, chao.p.peng@intel.com, Robert Hoo Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" If it is enabled, config-host.mak will have CONFIG_AVX512F_OPT defined. AVX512F instruction set is available since Intel Skylake, and can be enabled in compiling with -mavx512f. More info: https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf Signed-off-by: Robert Hoo Reviewed-by: Richard Henderson --- configure | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/configure b/configure index d57261e..a0b41ce 100755 --- a/configure +++ b/configure @@ -1395,6 +1395,11 @@ for opt do ;; --enable-avx2) avx2_opt="yes" ;; + --disable-avx512f) avx512f_opt="no" + ;; + --enable-avx512f) avx512f_opt="yes" + ;; + --enable-glusterfs) glusterfs="yes" ;; --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane) @@ -1825,6 +1830,7 @@ disabled with --disable-FEATURE, default is enabled if available: tcmalloc tcmalloc support jemalloc jemalloc support avx2 AVX2 optimization support + avx512f AVX512F optimization support replication replication support opengl opengl support virglrenderer virgl rendering support @@ -5518,6 +5524,36 @@ EOF fi fi +########################################## +# avx512f optimization requirement check +# +# There is no point enabling this if cpuid.h is not usable, +# since we won't be able to select the new routines. +# by default, it is turned off. +# if user explicitly want to enable it, check environment + +if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then + cat > $TMPC << EOF +#pragma GCC push_options +#pragma GCC target("avx512f") +#include +#include +static int bar(void *a) { + __m512i x = *(__m512i *)a; + return _mm512_test_epi64_mask(x, x); +} +int main(int argc, char *argv[]) +{ + return bar(argv[0]); +} +EOF + if ! compile_object "" ; then + avx512f_opt="no" + fi +else + avx512f_opt="no" +fi + ######################################## # check if __[u]int128_t is usable. @@ -6650,6 +6686,7 @@ echo "libxml2 $libxml2" echo "tcmalloc support $tcmalloc" echo "jemalloc support $jemalloc" echo "avx2 optimization $avx2_opt" +echo "avx512f optimization $avx512f_opt" echo "replication support $replication" echo "VxHS block device $vxhs" echo "bochs support $bochs" @@ -7200,6 +7237,10 @@ if test "$avx2_opt" = "yes" ; then echo "CONFIG_AVX2_OPT=y" >> $config_host_mak fi +if test "$avx512f_opt" = "yes" ; then + echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak +fi + if test "$lzo" = "yes" ; then echo "CONFIG_LZO=y" >> $config_host_mak fi From patchwork Fri Feb 28 02:24:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Hoo X-Patchwork-Id: 11411411 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E7C917E0 for ; Fri, 28 Feb 2020 02:26:58 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0FF78246A3 for ; Fri, 28 Feb 2020 02:26:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0FF78246A3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:40768 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j7VMf-00084u-9m for patchwork-qemu-devel@patchwork.kernel.org; Thu, 27 Feb 2020 21:26:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53929) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j7VM3-00079w-I1 for qemu-devel@nongnu.org; Thu, 27 Feb 2020 21:26:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j7VM2-00078b-A9 for qemu-devel@nongnu.org; Thu, 27 Feb 2020 21:26:19 -0500 Received: from mga03.intel.com ([134.134.136.65]:21710) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j7VM2-0006IW-2V for qemu-devel@nongnu.org; Thu, 27 Feb 2020 21:26:18 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2020 18:25:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,493,1574150400"; d="scan'208";a="238622583" Received: from sqa-gate.sh.intel.com (HELO robert-ivt.tsp.org) ([10.239.48.212]) by orsmga003.jf.intel.com with ESMTP; 27 Feb 2020 18:25:13 -0800 From: Robert Hoo To: qemu-devel@nongnu.org, pbonzini@redhat.com, richard.henderson@linaro.org, laurent@vivier.eu, philmd@redhat.com, berrange@redhat.com Subject: [PATCH v3 2/2] util: add util function buffer_zero_avx512() Date: Fri, 28 Feb 2020 10:24:56 +0800 Message-Id: <1582856696-45663-3-git-send-email-robert.hu@linux.intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1582856696-45663-1-git-send-email-robert.hu@linux.intel.com> References: <1582856696-45663-1-git-send-email-robert.hu@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.65 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: robert.hu@intel.com, chao.p.peng@intel.com, Robert Hoo Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" And intialize buffer_is_zero() with it, when Intel AVX512F is available on host. This function utilizes Intel AVX512 fundamental instructions which is faster than its implementation with AVX2 (in my unit test, with 4K buffer, on CascadeLake SP, ~36% faster, buffer_zero_avx512() V.S. buffer_zero_avx2()). Signed-off-by: Robert Hoo Reviewed-by: Richard Henderson --- include/qemu/cpuid.h | 3 +++ util/bufferiszero.c | 67 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h index 6930170..09fc245 100644 --- a/include/qemu/cpuid.h +++ b/include/qemu/cpuid.h @@ -45,6 +45,9 @@ #ifndef bit_AVX2 #define bit_AVX2 (1 << 5) #endif +#ifndef bit_AVX512F +#define bit_AVX512F (1 << 16) +#endif #ifndef bit_BMI2 #define bit_BMI2 (1 << 8) #endif diff --git a/util/bufferiszero.c b/util/bufferiszero.c index bfb2605..ce877b7 100644 --- a/util/bufferiszero.c +++ b/util/bufferiszero.c @@ -63,11 +63,11 @@ buffer_zero_int(const void *buf, size_t len) } } -#if defined(CONFIG_AVX2_OPT) || defined(__SSE2__) +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) || defined(__SSE2__) /* Do not use push_options pragmas unnecessarily, because clang * does not support them. */ -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) #pragma GCC push_options #pragma GCC target("sse2") #endif @@ -104,7 +104,7 @@ buffer_zero_sse2(const void *buf, size_t len) return _mm_movemask_epi8(_mm_cmpeq_epi8(t, zero)) == 0xFFFF; } -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) #pragma GCC pop_options #endif @@ -187,18 +187,54 @@ buffer_zero_avx2(const void *buf, size_t len) #pragma GCC pop_options #endif /* CONFIG_AVX2_OPT */ +#ifdef CONFIG_AVX512F_OPT +#pragma GCC push_options +#pragma GCC target("avx512f") +#include + +static bool +buffer_zero_avx512(const void *buf, size_t len) +{ + /* Begin with an unaligned head of 64 bytes. */ + __m512i t = _mm512_loadu_si512(buf); + __m512i *p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64); + __m512i *e = (__m512i *)(((uintptr_t)buf + len) & -64); + + /* Loop over 64-byte aligned blocks of 256. */ + while (p <= e) { + __builtin_prefetch(p); + if (unlikely(_mm512_test_epi64_mask(t, t))) { + return false; + } + t = p[-4] | p[-3] | p[-2] | p[-1]; + p += 4; + } + + t |= _mm512_loadu_si512(buf + len - 4 * 64); + t |= _mm512_loadu_si512(buf + len - 3 * 64); + t |= _mm512_loadu_si512(buf + len - 2 * 64); + t |= _mm512_loadu_si512(buf + len - 1 * 64); + + return !_mm512_test_epi64_mask(t, t); + +} +#pragma GCC pop_options +#endif + + /* Note that for test_buffer_is_zero_next_accel, the most preferred * ISA must have the least significant bit. */ -#define CACHE_AVX2 1 -#define CACHE_SSE4 2 -#define CACHE_SSE2 4 +#define CACHE_AVX512F 1 +#define CACHE_AVX2 2 +#define CACHE_SSE4 4 +#define CACHE_SSE2 8 /* Make sure that these variables are appropriately initialized when * SSE2 is enabled on the compiler command-line, but the compiler is * too old to support CONFIG_AVX2_OPT. */ -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) # define INIT_CACHE 0 # define INIT_ACCEL buffer_zero_int #else @@ -211,25 +247,35 @@ buffer_zero_avx2(const void *buf, size_t len) static unsigned cpuid_cache = INIT_CACHE; static bool (*buffer_accel)(const void *, size_t) = INIT_ACCEL; +static int length_to_accel; static void init_accel(unsigned cache) { bool (*fn)(const void *, size_t) = buffer_zero_int; if (cache & CACHE_SSE2) { fn = buffer_zero_sse2; + length_to_accel = 64; } #ifdef CONFIG_AVX2_OPT if (cache & CACHE_SSE4) { fn = buffer_zero_sse4; + length_to_accel = 64; } if (cache & CACHE_AVX2) { fn = buffer_zero_avx2; + length_to_accel = 64; + } +#endif +#ifdef CONFIG_AVX512F_OPT + if (cache & CACHE_AVX512F) { + fn = buffer_zero_avx512; + length_to_accel = 256; } #endif buffer_accel = fn; } -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) #include "qemu/cpuid.h" static void __attribute__((constructor)) init_cpuid_cache(void) @@ -255,6 +301,9 @@ static void __attribute__((constructor)) init_cpuid_cache(void) if ((bv & 6) == 6 && (b & bit_AVX2)) { cache |= CACHE_AVX2; } + if ((bv & 6) == 6 && (b & bit_AVX512F)) { + cache |= CACHE_AVX512F; + } } } cpuid_cache = cache; @@ -277,7 +326,7 @@ bool test_buffer_is_zero_next_accel(void) static bool select_accel_fn(const void *buf, size_t len) { - if (likely(len >= 64)) { + if (likely(len >= length_to_accel)) { return buffer_accel(buf, len); } return buffer_zero_int(buf, len);