The reason will be displayed to describe this comment to others. Learn more.
Just checking whether I understand correctly: aligned_end is not aligned, but good enough to serve as the end of the loop over aligned values. To make it really aligned we would need to do something like aligned_end = _Py_SIZE_ROUND_DOWN(_end, SIZEOF_SIZE_T)?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
Yes that is the gist of it. I tried something similar to _Py_SIZE_ROUND_DOWN and got segfaults so I opted for this simpler tried and true solution. The name aligned_end is probably not the best, but I can't think of a better name now.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
We could combine these two loops into a single loop right? Worst case we do a single loop over 32-1=31 bytes instead of two while loops (the loop over _p (7 steps) and the loop over p (3 steps)).
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
The more optimal solution is to do an unaligned load of a size_t at (end - SIZEOF_SIZE_T). That would remove the entire last while loop. I do not know if all architectures support unaligned loads however. I guess some could theoretically abort?
I single loop over 31 bytes taking 31 steps is less optimal than 2 while loops taking 10 steps in total. (Or even 7 in the case of 64-bit size_t, that would be the majority of platforms).
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
99% of production work were performance matters will be done on ARM64 (with 16-byte neon vectors) and X86-64 (with SSE2 vectors) other platforms will not be hurt by this decision. I think there is no reason to complicate the build with choices like this.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
picnixz reacted with thumbs up emoji
All reactions
👍1 reaction
Py_UCS4 max_char;
max_char = MAX_CHAR_ASCII;
mask = MASK_ASCII;
while (p < unrolled_end) {
STRINGLIB_CHAR bits = p[0] | p[1] | p[2] | p[3];
/* Loading 8 values at once allows platforms that have 16-byte vectors
The 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.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
IMO, we should prefer sizeof and _Alignofhere.
Things are a bit different in public headers (where sizeof is OK but _Alignof isn't) or the preprocessor (in #if, neither work).
(There is no C API WG formal guideline yet; this is a personal recommendation. If anyone wants a wider discussion, do that in Discourse.)
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
Is CPython supported on some platform where size_t is strictly greater than void*? I know this PR doesn't touch this conditional, but I'm curious. @encukou
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
This is not really about supported platforms (i.e. where we run the tests), or currently supported platforms.
We should aim for standard C whenever it's reasonable; if a speedup needs an extra assumption it should document that with this kind of #if.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The 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 __p or _q so pointer aliasing is not problematic. But I'd rather make this explicit rather than relying on the compiler to deduce this. MSVC and Clang do this scalarly despite the hint. GCC correctly vectorizes the load store and does not need the hint. I cannot judge all possible compilers out there. I think it is more likely that clang and MSVC will do the correct thing in the future with the hint than without it.
It would only save the restrict keyword as the (size_t *) cast is still needed, as that makes the rest of the code more readable. Are the 8 characters extra width that problematic?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
eendebakpt and thesamesam reacted with thumbs up emoji
The reason will be displayed to describe this comment to others. Learn more.
You technically have 3 blocks of SIZEOF_SIZE_T until you reach size_t_end. In this case, I'd suggest creating a macro which is the unrolling of that (I'm not sure the compiler knows this or not, but maybe it does).
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The reason will be displayed to describe this comment to others. Learn more.
Again, here you have only 3 chunks so maybe check whether you can unroll the loop once again (actually, just check whether the assembly with -O2 or -O3 unrolls stuff).
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
rhpvorderman reacted with thumbs up emoji
All reactions
👍1 reaction
size_t value = *(const size_t *) _p;
if (value & ASCII_CHAR_MASK)
break;
Expand Down
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.