Why would someone do this instead of re-using previous (or third-party) implementations? Of course unless it's all in different languages, but I don't think that's the case here.
I've been writing ring buffers wrong all these years
91–100 of 175 posts
Re: I've been writing ring buffers wrong all these years
#92His favored solution introduces subtlety and complexity. Remember that 20-year old binary search bug in the JDK a few years ago? That is the sort of bug that could be lurking in this solution. I understand not wanting to waste one slot. A third variable (first, last, count) isn't too bad. But if you really hate that third variable, why not just use first and count variables? You can then compute last from first and c…
I think he addressed that in the post:
The most common use for ring buffers is for it to be the intermediary between a concurrent reader and writer (be it two threads, to processes sharing memory, or a software process communicating with hardware). And for that, the index + size representation is kind of miserable. Both the reader and the writer will be writing to the length field, which is bad for caching. The read index and the length will also need to always be read and updated atomically, which would be awkward.
Re: I've been writing ring buffers wrong all these years
#93Earlier quoted context omitted.
Any choice? He only ever calls mask() after an increment. There are other ways of detecting the overflow and wrap to 0 that don't involve modulus.
Yes, any choice. Yes, that's not the case if you change the implementation in other ways in tandem - but then you are describing a different implementation. To mask where he does, any choice of mask will exhibit this problem (or other problems), mathematically. I can produce a proof if you need it. > He only ever calls mask() after an increment. I think you misunderstand what he's talking about. He calls mask at inse…
That said I'd mostly be using this kind of thing in a situation where i'd want to have a power of two sized buffer anyway.
Re: I've been writing ring buffers wrong all these years
#94Earlier quoted context omitted.
Do people's laces wear out? That's not a problem I've ever experienced.
Yes. I've had lots of laces wear out, especially the plasticky end parts.
Source: https://www.youtube.com/watch?v=Evcsj1gx1CE (I didn't forget it)
Re: I've been writing ring buffers wrong all these years
#95Earlier quoted context omitted.
> It's unclear to me why the focus on a 2^n sized buffer just so you can use & for the mask. The cost of a mask can probably be entirely buried in the instruction pipeline, so that it's hardly any more expensive than whatever it costs just to move from one register to another. Modulo requires division. Division requires a hardware algorithm that iterates, consuming multiple cycles (pipeline stall).
You do not need modulo or division to implement non-power-of-2 ring buffers. Because you will only increment by one. So instead of "x = x % BufferSize" you can do "if (x >= BufferSize) x -= BufferSize;" or similar. That's for "normal" ring buffers. I suspect that the design described in the article can be implemented for non power-of-two without division but I'll need to think about the details.
Re: I've been writing ring buffers wrong all these years
#96Earlier quoted context omitted.
It's not just an optimization, it's necessary for correct operation. With a non-power of two buffer the integer wraparound causes a discontinuity.
As far as I can tell that int wrap around could be avoided by - subtracting buffer size from both pointers once the read pointer has wrapped. - choosing a longer int for the math operation where possible That seems a small price for the freedom to be able to choose an appropriate buffer size.
Re: I've been writing ring buffers wrong all these years
#97> Join me next week for the exciting sequel to this post, "I've been tying my shoelaces wrong all these years". Probably. Use the Ian Knot: http://www.fieggen.com/shoelace/ianknot.htm Seriously, spend 20 mins practising this, and you'll never go back to the clumsy old way again.
The Ian Knot is quick, but as someone who never ties their shoes and just slips them on and off, I much prefer Ian's Secure Knot: http://www.fieggen.com/shoelace/secureknot.htm I usually tie this knot twice over the lifetime of a pair of shoes. Once when I get them, and once more when they're worn in and need to be tightened.
The really nice thing about this knot is that it looks really nice too so you can use them on both running shoes and dress shoes.
It makes no sense to teach the more common shoe tying knots.
Re: I've been writing ring buffers wrong all these years
#98He keeps stating the case of one-element ring buffer. Is that a real concern ever?
Re: I've been writing ring buffers wrong all these years
#99Earlier quoted context omitted.
Do people's laces wear out? That's not a problem I've ever experienced.
I've had a shoelaces break maybe 3-4 times on shoes I wore regularly for more than 2-3 years. It's annoying out of all proportion to the expense involved. (The plastic bits at the end can also get frayed and fall off, which happens more quickly, but I'm not sure knot style has much to do with that.)
Re: I've been writing ring buffers wrong all these years
#100Earlier quoted context omitted.
> It's unclear to me why the focus on a 2^n sized buffer just so you can use & for the mask. The cost of a mask can probably be entirely buried in the instruction pipeline, so that it's hardly any more expensive than whatever it costs just to move from one register to another. Modulo requires division. Division requires a hardware algorithm that iterates, consuming multiple cycles (pipeline stall).
You do not need modulo or division to implement non-power-of-2 ring buffers. Because you will only increment by one. So instead of "x = x % BufferSize" you can do "if (x >= BufferSize) x -= BufferSize;" or similar. That's for "normal" ring buffers. I suspect that the design described in the article can be implemented for non power-of-two without division but I'll need to think about the details.
I don't know if it would end up being faster, though.