Skip to content

Commit d6c1436

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 c4f97a1 commit d6c1436

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() {
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() {
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() {
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() {
@@ -203,6 +231,16 @@ static inline int zend_cpu_supports_avx() {
203231
static inline int zend_cpu_supports_avx2() {
204232
return zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
205233
}
234+
235+
static inline int zend_cpu_supports_avx512() {
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() {
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
@@ -626,6 +626,46 @@ extern "C++" {
626626
# define ZEND_INTRIN_AVX2_FUNC_DECL(func)
627627
#endif
628628

629+
#if PHP_HAVE_AVX512_SUPPORTS && defined(HAVE_FUNC_ATTRIBUTE_TARGET) || defined(ZEND_WIN32)
630+
#define ZEND_INTRIN_AVX512_RESOLVER 1
631+
#endif
632+
633+
#if defined(ZEND_INTRIN_AVX512_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
634+
# define ZEND_INTRIN_AVX512_FUNC_PROTO 1
635+
#elif defined(ZEND_INTRIN_AVX512_RESOLVER)
636+
# define ZEND_INTRIN_AVX512_FUNC_PTR 1
637+
#endif
638+
639+
#ifdef ZEND_INTRIN_AVX512_RESOLVER
640+
# ifdef HAVE_FUNC_ATTRIBUTE_TARGET
641+
# define ZEND_INTRIN_AVX512_FUNC_DECL(func) ZEND_API func __attribute__((target("avx512f,avx512cd,avx512vl,avx512dq,avx512bw")))
642+
# else
643+
# define ZEND_INTRIN_AVX512_FUNC_DECL(func) func
644+
# endif
645+
#else
646+
# define ZEND_INTRIN_AVX512_FUNC_DECL(func)
647+
#endif
648+
649+
#if PHP_HAVE_AVX512_VBMI_SUPPORTS && defined(HAVE_FUNC_ATTRIBUTE_TARGET)
650+
#define ZEND_INTRIN_AVX512_VBMI_RESOLVER 1
651+
#endif
652+
653+
#if defined(ZEND_INTRIN_AVX512_VBMI_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET)
654+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_PROTO 1
655+
#elif defined(ZEND_INTRIN_AVX512_VBMI_RESOLVER)
656+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_PTR 1
657+
#endif
658+
659+
#ifdef ZEND_INTRIN_AVX512_VBMI_RESOLVER
660+
# ifdef HAVE_FUNC_ATTRIBUTE_TARGET
661+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func) ZEND_API func __attribute__((target("avx512f,avx512cd,avx512vl,avx512dq,avx512bw,avx512vbmi")))
662+
# else
663+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func) func
664+
# endif
665+
#else
666+
# define ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(func)
667+
#endif
668+
629669
/* Intrinsics macros end. */
630670

631671
#ifdef ZEND_WIN32

build/php.m4

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,3 +2703,58 @@ AC_DEFUN([PHP_PATCH_CONFIG_HEADERS], [
27032703
$SED -e 's/^#undef PACKAGE_[^ ]*/\/\* & \*\//g' < $srcdir/$1 \
27042704
> $srcdir/$1.tmp && mv $srcdir/$1.tmp $srcdir/$1
27052705
])
2706+
2707+
dnl
2708+
dnl PHP_CHECK_AVX512_SUPPORTS
2709+
dnl
2710+
AC_DEFUN([PHP_CHECK_AVX512_SUPPORTS], [
2711+
AC_MSG_CHECKING([for avx512 supports in compiler])
2712+
save_CFLAGS="$CFLAGS"
2713+
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw $CFLAGS"
2714+
2715+
AC_LINK_IFELSE([AC_LANG_SOURCE([[
2716+
#include <immintrin.h>
2717+
int main() {
2718+
__m512i mask = _mm512_set1_epi32(0x1);
2719+
char out[32];
2720+
_mm512_storeu_si512(out, _mm512_shuffle_epi8(mask, mask));
2721+
return 0;
2722+
}]])], [
2723+
have_avx512_supports=1
2724+
AC_MSG_RESULT([yes])
2725+
], [
2726+
have_avx512_supports=0
2727+
AC_MSG_RESULT([no])
2728+
])
2729+
2730+
CFLAGS="$save_CFLAGS"
2731+
2732+
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_SUPPORTS],
2733+
[$have_avx512_supports], [Whether the compiler supports AVX512])
2734+
])
2735+
2736+
dnl
2737+
dnl PHP_CHECK_AVX512_VBMI_SUPPORTS
2738+
dnl
2739+
AC_DEFUN([PHP_CHECK_AVX512_VBMI_SUPPORTS], [
2740+
AC_MSG_CHECKING([for avx512 vbmi supports in compiler])
2741+
save_CFLAGS="$CFLAGS"
2742+
CFLAGS="-mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi $CFLAGS"
2743+
AC_LINK_IFELSE([AC_LANG_SOURCE([[
2744+
#include <immintrin.h>
2745+
int main() {
2746+
__m512i mask = _mm512_set1_epi32(0x1);
2747+
char out[32];
2748+
_mm512_storeu_si512(out, _mm512_permutexvar_epi8(mask, mask));
2749+
return 0;
2750+
}]])], [
2751+
have_avx512_vbmi_supports=1
2752+
AC_MSG_RESULT([yes])
2753+
], [
2754+
have_avx512_vbmi_supports=0
2755+
AC_MSG_RESULT([no])
2756+
])
2757+
CFLAGS="$save_CFLAGS"
2758+
AC_DEFINE_UNQUOTED([PHP_HAVE_AVX512_VBMI_SUPPORTS],
2759+
[$have_avx512_vbmi_supports], [Whether the compiler supports AVX512 VBMI])
2760+
])

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ dnl Check __builtin_cpu_init
489489
PHP_CHECK_BUILTIN_CPU_INIT
490490
dnl Check __builtin_cpu_supports
491491
PHP_CHECK_BUILTIN_CPU_SUPPORTS
492+
dnl Check AVX512
493+
PHP_CHECK_AVX512_SUPPORTS
494+
dnl Check AVX512 VBMI
495+
PHP_CHECK_AVX512_VBMI_SUPPORTS
492496

493497
dnl Check for __alignof__ support in the compiler
494498
AC_CACHE_CHECK(whether the compiler supports __alignof__, ac_cv_alignof_exists,[

0 commit comments

Comments
 (0)