Re: While we're at it
James Sutherland <[email protected]> Thu, 8 Apr 2010 19:55:32 +0100
| Newsgroups | gmane.network.djbdns |
|---|---|
| Message-ID | <[email protected]> |
2010/4/7 Dean Anderson <[email protected]>: > On Mon, 5 Apr 2010, Colm MacCárthaigh wrote: (snip) > But a complete word is brought into L2 cache to read one byte. When > aligned the next 3 tests access L2 cache at high speed and are > pipelined. A conditional jump to do one test at a time would slow it > down because the pipeline is flushed when the branch is taken. L1 cache not L2 - and the pipeline should only be flushed if the branch is mispredicted. Any half-decent branch prediction should know the conditional branch back to check the next byte (JNZ in x86-speak) is taken most of the time, so the misprediction will only occur when breaking out of the loop to return the result. On the original SPARC and MIPS static branch predictors, the first three lines of DJB's unrolled routine will be "predicted" correctly for the common case of a non-zero byte; only the loop back to the beginning will be mis-predicted. The later refinement, assuming that only backward branches are taken, will be correct for all except the final byte. >> > Show me a memory allocator that gives back unaligned memory, and I'll >> > show you how to fix that. Most of the time, we can be expect the memory >> > to be word-aligned. In the rare case it isn't, it won't matter too much. >> >> The issue is not that an allocator may return unaligned memory, but >> that you may wish to count the length of a string that does not start >> at the alignment boundary. For one trivial, but realistic, example; >> >> char * string = "Hello World"; // probably a word-aligned pointer >> int firstwordlength = strlen(string) - strlen(strtok(string, " ")); >> // second call is unaligned > > Sure. But one wants code that is fast in the most common case, and works > in the less common case. When parsing HTTP requests or DNS packets, I would expect nearly 75% of the initial data to be non-word-aligned (87.5% on machines with 64 bit words). With tinydns, the static data.cdb content already contains the length of each object, so there shouldn't be any strlen-type calls there either. With the simple byte by byte comparison, it doesn't really matter. I would not be at all surprised to find the extra overhead in the "clever" word by word version made it slower than the unrolled and branch-predicted byte approach. Of course, experimenting would be good - I'll see if I can find time to round up some actual figures, at least on x86 (-64) in the next few days. I would expect DJB did some profiling back when he first wrote that code and that's how he ended up with the 4 line unroll; I seem to recall he tended to check timing on SPARC and MIPS as well. -- James A Sutherland mobile +44 7977 563483; Skype jas88cam