Skip to content

Commit 749862e

Browse files
committed
base64: add avx512 and vbmi version.
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 <frank.du@intel.com>
1 parent d5d9900 commit 749862e

File tree

9 files changed

+492
-19
lines changed

9 files changed

+492
-19
lines changed

Zend/zend_cpuinfo.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ typedef enum _zend_cpu_feature {
6161

6262
/* EBX */
6363
ZEND_CPU_FEATURE_AVX2 = (1<<5 | ZEND_CPU_EBX_MASK),
64+
ZEND_CPU_FEATURE_AVX512F = (1<<16 | ZEND_CPU_EBX_MASK),
65+
ZEND_CPU_FEATURE_AVX512DQ = (1<<17 | ZEND_CPU_EBX_MASK),
66+
ZEND_CPU_FEATURE_AVX512CD = (1<<28 | ZEND_CPU_EBX_MASK),
67+
/* intentionally don't support = (1<<30 | ZEND_CPU_EBX_MASK) */
68+
/* intentionally don't support = (1<<31 | ZEND_CPU_EBX_MASK) */
6469

6570
/* EDX */
6671
ZEND_CPU_FEATURE_FPU = (1<<0 | ZEND_CPU_EDX_MASK),
@@ -174,6 +179,29 @@ static inline int zend_cpu_supports_avx2(void) {
174179
#endif
175180
return __builtin_cpu_supports("avx2");
176181
}
182+
183+
#if PHP_HAVE_AVX512_SUPPORTS
184+
ZEND_NO_SANITIZE_ADDRESS
185+
static inline int zend_cpu_supports_avx512(void) {
186+
#if PHP_HAVE_BUILTIN_CPU_INIT
187+
__builtin_cpu_init();
188+
#endif
189+
return __builtin_cpu_supports("avx512f") && __builtin_cpu_supports("avx512dq")
190+
&& __builtin_cpu_supports("avx512cd") && __builtin_cpu_supports("avx512bw")
191+
&& __builtin_cpu_supports("avx512vl");
192+
}
193+
#endif
194+
195+
#if PHP_HAVE_AVX512_VBMI_SUPPORTS
196+
ZEND_NO_SANITIZE_ADDRESS
197+
static inline int zend_cpu_supports_avx512_vbmi(void) {
198+
#if PHP_HAVE_BUILTIN_CPU_INIT
199+
__builtin_cpu_init();
200+
#endif
201+
return zend_cpu_supports_avx512() && __builtin_cpu_supports("avx512vbmi");
202+
}
203+
#endif
204+
177205
#else
178206

179207
static inline int zend_cpu_supports_sse2(void) {
@@ -203,6 +231,16 @@ static inline int zend_cpu_supports_avx(void) {
203231
static inline int zend_cpu_supports_avx2(void) {
204232
return zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
205233
}
234+
235+
static inline int zend_cpu_supports_avx512(void) {
236+
/* TODO: avx512_bw/avx512_vl use bit 30/31 which are reserved for mask */
237+
return 0;
238+
}
239+
240+
static zend_always_inline int zend_cpu_supports_avx512_vbmi(void) {
241+
/* TODO: avx512_vbmi use ECX of cpuid 7 */
242+
return 0;
243+
}
206244
#endif
207245

208246
/* __builtin_cpu_supports has pclmul from gcc9 */

Zend/zend_portability.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,46 @@ extern "C++" {
651651
# define ZEND_INTRIN_AVX2_FUNC_DECL(func)
652652
#endif
653653

654+
#if PHP_HAVE_AVX512_SUPPORTS && defined(HAVE_FUNC_ATTRIBUTE_TARGET) || defined(ZEND_WIN32)
655+
#define ZEND_INTRIN_AVX512_RESOLVER 1
656+
#endif
657+
658+
#if defined(ZEND_INTRIN_AVX512_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
659+
# define ZEND_INTRIN_AVX512_FUNC_PROTO 1
660+
#elif defined(ZEND_INTRIN_AVX512_RESOLVER)
661+
# define ZEND_INTRIN_AVX512_FUNC_PTR 1
662+
#endif
663+
664+
#ifdef ZEND_INTRIN_AVX512_RESOLVER
665+
# ifdef HAVE_FUNC_ATTRIBUTE_TARGET
666+
# define ZEND_INTRIN_AVX512_FUNC_DECL(func) ZEND_API func __attribute__((target("avx512f,avx512cd,avx512vl,avx512dq,avx512bw")))
667+
# else
668+
# define ZEND_INTRIN_AVX512_FUNC_DECL(func) func
669+
# endif
670+
#else
671+
# define ZEND_INTRIN_AVX512_FUNC_DECL(func)
672+
#endif
673+
674+
#if PHP_HAVE_AVX512_VBMI_SUPPORTS && defined(HAVE_FUNC_ATTRIBUTE_TARGET)
675+
#define ZEND_INTRIN_AVX512_VBMI_RESOLVER 1
676+
#endif
677+
678+
#if defined(ZEND_INTRIN_AVX512_VBMI_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
679+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_PROTO 1
680+
#elif defined(ZEND_INTRIN_AVX512_VBMI_RESOLVER)
681+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_PTR 1
682+
#endif
683+
684+
#ifdef ZEND_INTRIN_AVX512_VBMI_RESOLVER
685+
# ifdef HAVE_FUNC_ATTRIBUTE_TARGET
686+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func) ZEND_API func __attribute__((target("avx512f,avx512cd,avx512vl,avx512dq,avx512bw,avx512vbmi")))
687+
# else
688+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func) func
689+
# endif
690+
#else
691+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func)
692+
#endif
693+
654694
/* Intrinsics macros end. */
655695

656696
#ifdef ZEND_WIN32

build/php.m4

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,3 +2786,58 @@ AC_DEFUN([PHP_CHECK_PROCCTL],
27862786
AC_MSG_RESULT([no])
27872787
])
27882788
])
2789+
2790+
dnl
2791+
dnl PHP_CHECK_AVX512_SUPPORTS
2792+
dnl
2793+
AC_DEFUN([PHP_CHECK_AVX512_SUPPORTS], [
2794+
AC_MSG_CHECKING([for avx512 supports in compiler])
2795+
save_CFLAGS="$CFLAGS"
2796+
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw $CFLAGS"
2797+
2798+
AC_LINK_IFELSE([AC_LANG_SOURCE([[
2799+
#include <immintrin.h>
2800+
int main() {
2801+
__m512i mask = _mm512_set1_epi32(0x1);
2802+
char out[32];
2803+
_mm512_storeu_si512(out, _mm512_shuffle_epi8(mask, mask));
2804+
return 0;
2805+
}]])], [
2806+
have_avx512_supports=1
2807+
AC_MSG_RESULT([yes])
2808+
], [
2809+
have_avx512_supports=0
2810+
AC_MSG_RESULT([no])
2811+
])
2812+
2813+
CFLAGS="$save_CFLAGS"
2814+
2815+
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_SUPPORTS],
2816+
[$have_avx512_supports], [Whether the compiler supports AVX512])
2817+
])
2818+
2819+
dnl
2820+
dnl PHP_CHECK_AVX512_VBMI_SUPPORTS
2821+
dnl
2822+
AC_DEFUN([PHP_CHECK_AVX512_VBMI_SUPPORTS], [
2823+
AC_MSG_CHECKING([for avx512 vbmi supports in compiler])
2824+
save_CFLAGS="$CFLAGS"
2825+
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi $CFLAGS"
2826+
AC_LINK_IFELSE([AC_LANG_SOURCE([[
2827+
#include <immintrin.h>
2828+
int main() {
2829+
__m512i mask = _mm512_set1_epi32(0x1);
2830+
char out[32];
2831+
_mm512_storeu_si512(out, _mm512_permutexvar_epi8(mask, mask));
2832+
return 0;
2833+
}]])], [
2834+
have_avx512_vbmi_supports=1
2835+
AC_MSG_RESULT([yes])
2836+
], [
2837+
have_avx512_vbmi_supports=0
2838+
AC_MSG_RESULT([no])
2839+
])
2840+
CFLAGS="$save_CFLAGS"
2841+
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_VBMI_SUPPORTS],
2842+
[$have_avx512_vbmi_supports], [Whether the compiler supports AVX512 VBMI])
2843+
])

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ dnl Check prctl
518518
PHP_CHECK_PRCTL
519519
dnl Check procctl
520520
PHP_CHECK_PROCCTL
521+
dnl Check AVX512
522+
PHP_CHECK_AVX512_SUPPORTS
523+
dnl Check AVX512 VBMI
524+
PHP_CHECK_AVX512_VBMI_SUPPORTS
521525

522526
dnl Check for __alignof__ support in the compiler
523527
AC_CACHE_CHECK(whether the compiler supports __alignof__, ac_cv_alignof_exists,[

0 commit comments

Comments
 (0)