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:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user