Skip to content

Commit

Permalink
base64: add avx512 and vbmi version.
Browse files Browse the repository at this point in the history
1. Implementation based on https://github.com/WojciechMula/base64simd
2. Only runtime path is added to reduce the complexity of SIMD variants.
3. Expand test case to cover SIMD implementation.

Signed-off-by: Frank Du <[email protected]>
  • Loading branch information
frankdjx committed Oct 21, 2020
1 parent 7f595ba commit 7748c2e
Show file tree
Hide file tree
Showing 9 changed files with 490 additions and 19 deletions.
36 changes: 36 additions & 0 deletions Zend/zend_cpuinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ typedef enum _zend_cpu_feature {

/* EBX */
ZEND_CPU_FEATURE_AVX2 = (1<<5 | ZEND_CPU_EBX_MASK),
ZEND_CPU_FEATURE_AVX512F = (1<<16 | ZEND_CPU_EBX_MASK),
ZEND_CPU_FEATURE_AVX512DQ = (1<<17 | ZEND_CPU_EBX_MASK),
ZEND_CPU_FEATURE_AVX512CD = (1<<28 | ZEND_CPU_EBX_MASK),
/*intentionally don't support = (1<<30 | ZEND_CPU_EBX_MASK)*/
/*intentionally don't support = (1<<31 | ZEND_CPU_EBX_MASK)*/

/* EDX */
ZEND_CPU_FEATURE_FPU = (1<<0 | ZEND_CPU_EDX_MASK),
Expand Down Expand Up @@ -185,6 +190,28 @@ static zend_always_inline int zend_cpu_supports_avx2() {
#endif
return __builtin_cpu_supports("avx2");
}

#if PHP_HAVE_AVX512_SUPPORTS
ZEND_NO_SANITIZE_ADDRESS
static zend_always_inline int zend_cpu_supports_avx512() {
#if PHP_HAVE_BUILTIN_CPU_INIT
__builtin_cpu_init();
#endif
return __builtin_cpu_supports("avx512f") && __builtin_cpu_supports("avx512dq")
&& __builtin_cpu_supports("avx512cd") && __builtin_cpu_supports("avx512bw")
&& __builtin_cpu_supports("avx512vl");
}
#endif

#if PHP_HAVE_AVX512_VBMI_SUPPORTS
ZEND_NO_SANITIZE_ADDRESS
static zend_always_inline int zend_cpu_supports_avx512_vbmi() {
#if PHP_HAVE_BUILTIN_CPU_INIT
__builtin_cpu_init();
#endif
return zend_cpu_supports_avx512() && __builtin_cpu_supports("avx512vbmi");
}
#endif
#else

static zend_always_inline int zend_cpu_supports_sse2() {
Expand Down Expand Up @@ -219,6 +246,15 @@ static zend_always_inline int zend_cpu_supports_avx2() {
return zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
}

static zend_always_inline int zend_cpu_supports_avx512() {
/* TODO: avx512_bw/avx512_vl use bit 30/31 which are reserved for mask */
return 0;
}

static zend_always_inline int zend_cpu_supports_avx512_vbmi() {
/* TODO: avx512_vbmi use ECX of cpuid 7 */
return 0;
}
#endif

#endif
40 changes: 40 additions & 0 deletions Zend/zend_portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,46 @@ extern "C++" {
# define ZEND_INTRIN_AVX2_FUNC_DECL(func)
#endif

#if PHP_HAVE_AVX512_SUPPORTS && defined(HAVE_FUNC_ATTRIBUTE_TARGET) || defined(ZEND_WIN32)
#define ZEND_INTRIN_AVX512_RESOLVER 1
#endif

#if defined(ZEND_INTRIN_AVX512_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
# define ZEND_INTRIN_AVX512_FUNC_PROTO 1
#elif defined(ZEND_INTRIN_AVX512_RESOLVER)
# define ZEND_INTRIN_AVX512_FUNC_PTR 1
#endif

#ifdef ZEND_INTRIN_AVX512_RESOLVER
# ifdef HAVE_FUNC_ATTRIBUTE_TARGET
# define ZEND_INTRIN_AVX512_FUNC_DECL(func) ZEND_API func __attribute__((target("avx512f,avx512cd,avx512vl,avx512dq,avx512bw")))
# else
# define ZEND_INTRIN_AVX512_FUNC_DECL(func) func
# endif
#else
# define ZEND_INTRIN_AVX512_FUNC_DECL(func)
#endif

#if PHP_HAVE_AVX512_VBMI_SUPPORTS && defined(HAVE_FUNC_ATTRIBUTE_TARGET)
#define ZEND_INTRIN_AVX512_VBMI_RESOLVER 1
#endif

#if defined(ZEND_INTRIN_AVX512_VBMI_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
# define ZEND_INTRIN_AVX512_VBMI_FUNC_PROTO 1
#elif defined(ZEND_INTRIN_AVX512_VBMI_RESOLVER)
# define ZEND_INTRIN_AVX512_VBMI_FUNC_PTR 1
#endif

#ifdef ZEND_INTRIN_AVX512_VBMI_RESOLVER
# ifdef HAVE_FUNC_ATTRIBUTE_TARGET
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func) ZEND_API func __attribute__((target("avx512f,avx512cd,avx512vl,avx512dq,avx512bw,avx512vbmi")))
# else
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func) func
# endif
#else
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func)
#endif

/* Intrinsics macros end. */

#ifdef ZEND_WIN32
Expand Down
55 changes: 55 additions & 0 deletions build/php.m4
Original file line number Diff line number Diff line change
Expand Up @@ -2703,3 +2703,58 @@ AC_DEFUN([PHP_PATCH_CONFIG_HEADERS], [
$SED -e 's/^#undef PACKAGE_[^ ]*/\/\* & \*\//g' < $srcdir/$1 \
> $srcdir/$1.tmp && mv $srcdir/$1.tmp $srcdir/$1
])

dnl
dnl PHP_CHECK_AVX512_SUPPORTS
dnl
AC_DEFUN([PHP_CHECK_AVX512_SUPPORTS], [
AC_MSG_CHECKING([for avx512 supports in compiler])
save_CFLAGS="$CFLAGS"
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw $CFLAGS"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <immintrin.h>
int main() {
__m512i mask = _mm512_set1_epi32(0x1);
char out[32];
_mm512_storeu_si512(out, _mm512_shuffle_epi8(mask, mask));
return 0;
}]])], [
have_avx512_supports=1
AC_MSG_RESULT([yes])
], [
have_avx512_supports=0
AC_MSG_RESULT([no])
])
CFLAGS="$save_CFLAGS"
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_SUPPORTS],
[$have_avx512_supports], [Whether the compiler supports AVX512])
])

dnl
dnl PHP_CHECK_AVX512_VBMI_SUPPORTS
dnl
AC_DEFUN([PHP_CHECK_AVX512_VBMI_SUPPORTS], [
AC_MSG_CHECKING([for avx512 vbmi supports in compiler])
save_CFLAGS="$CFLAGS"
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi $CFLAGS"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <immintrin.h>
int main() {
__m512i mask = _mm512_set1_epi32(0x1);
char out[32];
_mm512_storeu_si512(out, _mm512_permutexvar_epi8(mask, mask));
return 0;
}]])], [
have_avx512_vbmi_supports=1
AC_MSG_RESULT([yes])
], [
have_avx512_vbmi_supports=0
AC_MSG_RESULT([no])
])
CFLAGS="$save_CFLAGS"
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_VBMI_SUPPORTS],
[$have_avx512_vbmi_supports], [Whether the compiler supports AVX512 VBMI])
])
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,10 @@ dnl Check __builtin_cpu_init
PHP_CHECK_BUILTIN_CPU_INIT
dnl Check __builtin_cpu_supports
PHP_CHECK_BUILTIN_CPU_SUPPORTS
dnl Check AVX512
PHP_CHECK_AVX512_SUPPORTS
dnl Check AVX512 VBMI
PHP_CHECK_AVX512_VBMI_SUPPORTS

dnl Check for __alignof__ support in the compiler
AC_CACHE_CHECK(whether the compiler supports __alignof__, ac_cv_alignof_exists,[
Expand Down
Loading

0 comments on commit 7748c2e

Please sign in to comment.