Repository navigation
gh-120196: Faster ascii_decode and find_max_char implementations #120212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
a54bf86
71ff457
98a6449
10527c6
f0f4139
849a068
fad19a0
f04bb2c
cd0fc5e
8f0fd56
37aee7a
a6fc417
104ca62
d465517
1ce308e
48f1e84
21de804
1ec2113
0258ae0
ec76b74
845eb4e
f8cc68d
89ab2c9
002b7ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,7 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) | |
| } | ||
|
|
||
| /* On 64-bit platforms with 128-bit vectors (x86-64, arm64) the | ||
| compiler can load 4 size_t values into two 16-byte vectors and do a | ||
| compiler can load 4 size_t values into two 16-byte vectors and do a | ||
| vector bitwise OR. */ | ||
| const size_t *_p = (const size_t *)p; | ||
| while (_p < unrolled_end) { | ||
|
|
@@ -98,7 +98,7 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) | |
| max_char = MAX_CHAR_ASCII; | ||
| mask = MASK_ASCII; | ||
| while (p < unrolled_end) { | ||
| /* Loading 8 values at once allows platforms that have 16-byte vectors | ||
| /* Loading 8 values at once allows platforms that have 16-byte vectors | ||
| to do a vector load and vector bitwise OR. */ | ||
| STRINGLIB_CHAR bits = p[0] | p[1] | p[2] | p[3] | p[4] | p[5] | p[6] | p[7]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel that those vector load could be macros, for clarity purposes. It would then be optimized by the compiler but having them as macros might be helpful for future work.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would to not have a macro, the code is good as it is. |
||
| if (bits & mask) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4700,7 +4700,7 @@ static Py_ssize_t | |
| ascii_decode(const char *start, const char *end, Py_UCS1 *dest) | ||
| { | ||
| const char *p = start; | ||
| Py_ssize_t length = end - start; | ||
| Py_ssize_t length = end - start; | ||
| const char *size_t_end = end - SIZEOF_SIZE_T; | ||
| const char *unroll_end = end - (4 * SIZEOF_SIZE_T); | ||
|
rhpvorderman marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
@@ -4714,7 +4714,7 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) | |
| const char *_p = p; | ||
| Py_UCS1 * q = dest; | ||
| while (_p <= unroll_end) { | ||
| const size_t *restrict __p = (const size_t *)_p; | ||
| const size_t *restrict __p = (const size_t *)_p; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the restrict keyword and the assignment to value0, ..., value3 required for the compiler? If not, then this code can be written more compact.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general I think the compiler can judge from the function that no writes happen in either It would only save the |
||
| size_t value = __p[0] | __p[1] | __p[2] | __p[3]; | ||
| if (if value & ASCII_CHAR_MASK) { | ||
| break; | ||
|
|
@@ -4751,7 +4751,7 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) | |
| /* Help allocation */ | ||
| const char *_p = p; | ||
| while (_p <= unroll_end) { | ||
| const size_t *restrict __p = (const size_t *)_p; | ||
| const size_t *restrict __p = (const size_t *)_p; | ||
| size_t value = __p[0] | __p[1] | __p[2] | __p[3]; | ||
| if (if value & ASCII_CHAR_MASK) { | ||
| break; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here, you would have some #if arch == ... to choose between 4 or 8 values.