3 ms·
> It’s the “load 5 bytes” and “store 5 bytes” that I don’t have a good solution for. You build that out of "load 16 bytes" and "store 16 bytes" operations.
by dragontamer 4y ago
> It’s the “load 5 bytes” and “store 5 bytes” that I don’t have a good solution for.
You build that out of "load 16 bytes" and "store 16 bytes" operations.
register = [news.YCOMBINATOR]
isValid = [00000FFFFFFFFFFF]; // "F" is really 0xFF, but you get the gist
// isValid was generated because you were focusing on the YCOMBINATOR part
// of the DNS entry: news . YCOMBINATOR . com. YCOMBINATOR there to focus
// upon the current data being considered, while "news." and "com" should
// remain untouched
register = (register | ((register >= 'A' & register <='Z') << 5));
register = register & isValid;
toWrite = writeLocation & (~isValid);
toWrite = toWrite | register;
writeLocation = toWrite;
If you're doing things in-place, then writeLocation could be a copy of "register" from the 1st step.
- dzaima 4y agoDoesn't work if you don't have read access past (or before) the segment you want. And, as GP says, asan won't like reading/writing out-of-bounds (even if temporarily) either. Probably very unlikely to happen, but that's not really something you want to be betting on.
- dragontamer 4y agoI get it now. Thanks for explaining. That particular problem is solved by rounding up to the SIMD-width for all SIMD-allocations. Ex: 13-size gets rounded up to 16-sized alloc. 25-size gets rounded up to a 32-sized alloc. This, in combination of "processing of garbage" and "Valid" flags, should cover all the cases. EDIT: At least, for the "dynamic" strings that are loaded into memory. Someone elsewhere has brought up compiler strings, which seem complicated to me (I'm not sure if we have any alignment guarantees, and therefore are forced to process strings sequentially, one byte at a time if they're from the compiler).
- janwas 4y agoI agree padding is a good solution when you can arrange it. In Highway we also use the blending/bit-select you mention: https://github.com/google/highway/blob/master/hwy/ops/generic_ops-inl.h#L90 https://github.com/google/highway/blob/master/hwy/ops/generi... If HWY_MEM_OPS_MIGHT_FAULT, which is true if using ASAN or AVX2 (because AMD reserves the right to fault even if mask=0), we actually use a scalar loop. I'm curious if anyone has data indicating that a jump table is faster, enough to make a difference?
- dragontamer 4y ago> I'm curious if anyone has data indicating that a jump table is faster, enough to make a difference? Anything that touches the branch predictors on these modern, crazy CPUs, is going to be too complicated to really understand from a performance perspective! I'm pretty sure that jump tables / if statements all touch the branch predictor. Things will be high performance if the branch is consistently predicted correctly, but good luck figuring that out without just running the darn program on a CPU.
- dzaima 4y agoBetween a jump table and a scalar loop, the loop will screw with the branch predictor more. A jump table has the potential to be faster by doing SIMD, at the cost of taking more icache.