Skip to content

Commit a9437ce

Browse files
authored
base64: add avx512 and vbmi version. (#6361)
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 19a7281 commit a9437ce

File tree

10 files changed

+539
-5
lines changed

10 files changed

+539
-5
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
@@ -2807,3 +2807,58 @@ AC_DEFUN([PHP_CHECK_PROCCTL],
28072807
AC_MSG_RESULT([no])
28082808
])
28092809
])
2810+
2811+
dnl
2812+
dnl PHP_CHECK_AVX512_SUPPORTS
2813+
dnl
2814+
AC_DEFUN([PHP_CHECK_AVX512_SUPPORTS], [
2815+
AC_MSG_CHECKING([for avx512 supports in compiler])
2816+
save_CFLAGS="$CFLAGS"
2817+
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw $CFLAGS"
2818+
2819+
AC_LINK_IFELSE([AC_LANG_SOURCE([[
2820+
#include <immintrin.h>
2821+
int main() {
2822+
__m512i mask = _mm512_set1_epi32(0x1);
2823+
char out[32];
2824+
_mm512_storeu_si512(out, _mm512_shuffle_epi8(mask, mask));
2825+
return 0;
2826+
}]])], [
2827+
have_avx512_supports=1
2828+
AC_MSG_RESULT([yes])
2829+
], [
2830+
have_avx512_supports=0
2831+
AC_MSG_RESULT([no])
2832+
])
2833+
2834+
CFLAGS="$save_CFLAGS"
2835+
2836+
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_SUPPORTS],
2837+
[$have_avx512_supports], [Whether the compiler supports AVX512])
2838+
])
2839+
2840+
dnl
2841+
dnl PHP_CHECK_AVX512_VBMI_SUPPORTS
2842+
dnl
2843+
AC_DEFUN([PHP_CHECK_AVX512_VBMI_SUPPORTS], [
2844+
AC_MSG_CHECKING([for avx512 vbmi supports in compiler])
2845+
save_CFLAGS="$CFLAGS"
2846+
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi $CFLAGS"
2847+
AC_LINK_IFELSE([AC_LANG_SOURCE([[
2848+
#include <immintrin.h>
2849+
int main() {
2850+
__m512i mask = _mm512_set1_epi32(0x1);
2851+
char out[32];
2852+
_mm512_storeu_si512(out, _mm512_permutexvar_epi8(mask, mask));
2853+
return 0;
2854+
}]])], [
2855+
have_avx512_vbmi_supports=1
2856+
AC_MSG_RESULT([yes])
2857+
], [
2858+
have_avx512_vbmi_supports=0
2859+
AC_MSG_RESULT([no])
2860+
])
2861+
CFLAGS="$save_CFLAGS"
2862+
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_VBMI_SUPPORTS],
2863+
[$have_avx512_vbmi_supports], [Whether the compiler supports AVX512 VBMI])
2864+
])

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ dnl Check prctl
520520
PHP_CHECK_PRCTL
521521
dnl Check procctl
522522
PHP_CHECK_PROCCTL
523+
dnl Check AVX512
524+
PHP_CHECK_AVX512_SUPPORTS
525+
dnl Check AVX512 VBMI
526+
PHP_CHECK_AVX512_VBMI_SUPPORTS
523527

524528
dnl Check for __alignof__ support in the compiler
525529
AC_CACHE_CHECK(whether the compiler supports __alignof__, ac_cv_alignof_exists,[

0 commit comments

Comments
 (0)