1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Optimize HT_HASH_RESET (#11059)

Commit d835de1993 added support for AVX2 in hash table initialization
code. The same kind of code also occurs for HT_HASH_RESET. However, this
place was forgotten in that patch. That is unfortunate, because a loop
is just when there may be the most benefit from this SIMD sequence.
Furthermore, the NEON special handling exists in the initialization code
but is also missing from HT_HASH_RESET, so add this as well.
This commit is contained in:
Niels Dossche
2023-04-12 19:14:54 +02:00
committed by GitHub
parent aae20cd119
commit 6ebd08bb33

View File

@@ -31,6 +31,12 @@
# include <mmintrin.h>
# include <emmintrin.h>
#endif
#if defined(__AVX2__)
# include <immintrin.h>
#endif
#if defined(__aarch64__) || defined(_M_ARM64)
# include <arm_neon.h>
#endif
#ifdef WORDS_BIGENDIAN
# define ZEND_ENDIAN_LOHI(lo, hi) hi; lo;
@@ -460,7 +466,21 @@ struct _zend_array {
HT_PACKED_SIZE_EX((ht)->nTableSize, (ht)->nTableMask)
#define HT_PACKED_USED_SIZE(ht) \
(HT_HASH_SIZE((ht)->nTableMask) + ((size_t)(ht)->nNumUsed * sizeof(zval)))
#ifdef __SSE2__
#if defined(__AVX2__)
# define HT_HASH_RESET(ht) do { \
char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
__m256i ymm0 = _mm256_setzero_si256(); \
ymm0 = _mm256_cmpeq_epi64(ymm0, ymm0); \
ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
do { \
_mm256_storeu_si256((__m256i*)p, ymm0); \
_mm256_storeu_si256((__m256i*)(p+32), ymm0); \
p += 64; \
size -= 64; \
} while (size != 0); \
} while (0)
#elif defined(__SSE2__)
# define HT_HASH_RESET(ht) do { \
char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
@@ -476,6 +496,21 @@ struct _zend_array {
size -= 64; \
} while (size != 0); \
} while (0)
#elif defined(__aarch64__) || defined(_M_ARM64)
# define HT_HASH_RESET(ht) do { \
char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
int32x4_t t = vdupq_n_s32(-1); \
ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
do { \
vst1q_s32((int32_t*)p, t); \
vst1q_s32((int32_t*)(p+16), t); \
vst1q_s32((int32_t*)(p+32), t); \
vst1q_s32((int32_t*)(p+48), t); \
p += 64; \
size -= 64; \
} while (size != 0); \
} while (0)
#else
# define HT_HASH_RESET(ht) \
memset(&HT_HASH(ht, (ht)->nTableMask), HT_INVALID_IDX, HT_HASH_SIZE((ht)->nTableMask))