Skip to content

Commit 68a7578

Browse files
Sebastian Popnikic
Sebastian Pop
authored andcommitted
[AArch64] use rev64 to reverse strings
The execution time goes from 4.388s down to 0.563s on a Graviton A1 instance for the benchmark: function reverse_strings() { $a = "foo"; for ($i = 0; $i < 100000; $i++) { strrev($a); $a .= "o"; } }
1 parent d9a2d76 commit 68a7578

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

ext/standard/string.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,6 +3536,8 @@ PHP_FUNCTION(strtr)
35363536
Reverse a string */
35373537
#if ZEND_INTRIN_SSSE3_NATIVE
35383538
#include <tmmintrin.h>
3539+
#elif defined(__aarch64__)
3540+
#include <arm_neon.h>
35393541
#endif
35403542
PHP_FUNCTION(strrev)
35413543
{
@@ -3568,6 +3570,19 @@ PHP_FUNCTION(strrev)
35683570
e -= 16;
35693571
} while (e - s > 15);
35703572
}
3573+
#elif defined(__aarch64__)
3574+
if (e - s > 15) {
3575+
do {
3576+
const uint8x16_t str = vld1q_u8((uint8_t *)(e - 15));
3577+
/* Synthesize rev128 with a rev64 + ext. */
3578+
const uint8x16_t rev = vrev64q_u8(str);
3579+
const uint8x16_t ext = (uint8x16_t)
3580+
vextq_u64((uint64x2_t)rev, (uint64x2_t)rev, 1);
3581+
vst1q_u8((uint8_t *)p, ext);
3582+
p += 16;
3583+
e -= 16;
3584+
} while (e - s > 15);
3585+
}
35713586
#endif
35723587
while (e >= s) {
35733588
*p++ = *e--;

0 commit comments

Comments
 (0)