Daniel Fortunov's Adventures in Software Development » Going Quad: Optimal toiletpaper strategies for the modern geek
4 Comments
- Add comment |
Back to Software Development Blog Written on 13-Jan-2009 by asquiHow many similarities can be drawn between concurrent software development and toilet paper dispensers? Let me try and see...
The bathrooms at the office have a dual toilet-paper holder for the increased demands of communal use. (For the curious, a little internet searching indicates this is the A838 "Toilet Paper Holder for Two Rolls" in chrome-plated steel, produced by Chia Cheng World Industrial Co. Ltd.) A little while ago they were renovating one of the two bathrooms on our floor and to cope with the expected 100% increase in demand (i.e. MTBF of toilet-paper holders reduced by half, without increase in frequency of janitorial visits) they decided to double-up on the A838s.
I often suffer from the problem of indecisiveness, so being presented with four rolls to choose from was a bit of a complication for me. Being concerned with concurrent programming, I wanted to devise an optimal and robust concurrent algorithm for deciding which roll to pick.
First some assumptions:
Now lets explore some possible strategies:
1. Pick a (non-empty) roll at random
If everyone picked a random roll then, on average, all the rolls would be exhausted simultaneously. This is sub-optimal because the janitor should be able to replace empty rolls on each visit, keeping the cubicle operational at all times. If all rolls were used at the same rate then the janitor would either need to have perfect timing, and arrive to replenish the supply just as all four rolls are simultaneously exhausted, or replace all four rolls before they are exhausted. (And I don't want to get into a digression about janitorial algorithms involving swapping partially used rolls between cubicles...)
Also, it is non-trivial for a human to make a statistically un-biased random choice. I'm not in the habit of using a pseudo-random number generator in a bathroom stall — that would be weird. (Unlike extensive methodical thinking about toilet paper choice strategies, which is clearly normal.)
2. Pick the first (non-empty) roll in a pre-defined order
Review the rolls in a well-known order, for example left-to-right top-to-bottom, and use the first non-empty roll you find.
If everyone did this, using the same ordering, then the rolls would always get exhausted in that order. The janitor would even be able to make the optimisation of knowing that if the top-left roll is non-empty he doesn't need to inspect any other rolls because they are guaranteed to be non-empty. (This, of course, is not a great optimisation because inspecting the top-left roll is almost as intensive as inspecting all four — all four rolls are in the same 'cache line', if you will.)1
If some users deviate from this strategy (perhaps visitors to the building cannot be expected to be up to speed with all of the toilet paper training provided) then this strategy becomes less effective. The rolls may not necessarily be exhausted in the normal order, and the janitor's short-sighted (pun intended) optimisation could lead to an un-replenished roll (or three)!
3. Pick the largest roll
Using the roll which has the most paper left seems a sensible strategy. However this behaviour, averaged over many iterations, would result in all of the rolls being used up at roughly the same rate. This strategy is therefore, on average, equivalent to strategy number 1.
4. Pick the smallest roll
In the same way that strategy 3 is equivalent to strategy 1, this strategy is analogous to strategy 2. If everyone picked the smallest roll then the first roll to be chosen would be chosen for all subsequent dispensation until it is exhausted. This would only be equivalent to strategy 2 if a well-known precedence order was used to tie-break rolls of equivalent size.
Consider an adversary with unlimited resources who's goal is to disrupt the operation of this strategy. They could employ a compensating usage pattern which reduces the efficiency of any given strategy to that of strategy number 1. (They would need to consume at most three times the paper of the user they are 'compensating' for to achieve this.)
However, this is somewhat of a moot point. An adversary with unlimited resources could just consume all of the available toilet paper instantaneously, or simultaneously engage all of the available stalls, urinals (where applicable), sinks, paper towel dispensers, and hand dryers, rendering the bathroom completely unusable and unserviceable by a janitor. This, therefore, must be considered a failing of the security model at a higher-level than the paper usage strategy.
I guess the bathroom design was not evaluated against any threat models.
As specified in assumption 4, we need to be future-proof for the event of a new-age trend for communal toilet paper holders, located at the core of a star-shaped cluster of bathroom stalls. This brings the benefits of increased janitor efficiency and load balancing, but brings about some concurrency challenges.
What happens if two users reach for the same roll simultaneously? We would need some sort of synchronisation mechanism.
Or what if someone dispenses some paper from your selected roll just as you're about to reach for it? You may then need to re-evaluate your choice of roll, in light of the new roll sizes. Could you get into a situation where demand for this shared resource is so highly contended that you never make any forward progress? If your roll selection algorithm is slower to execute than everyone elses' then this is a very real possibility!
Worst of all would be the scenario where there is a bug in the dispenser allowing you and someone else to acquire the same square(s) of paper, and the other person happens to be quicker to "dispose" it than you. You think you have exclusive ownership of the square(s) but they disappear while you're using them!
This is why concurrent code needs to be well thought out and thoroughly reviewed.
Why force the user to make a choice when they don't need to?
As is often the case with the design of every day things, there is a more elegant design solution that sidesteps a lot of these problems. After the renovation was complete, the indecision was over. New dispensers hold a stack of 3 rolls; only the bottom one can be 'active' and once it's empty the one above drops down to take its place.
Now janitors can operate with low paper-waste, and users don't need any training. Well, almost...
In this example the top visual inspection port has been exploited to compromise the top roll for out-of-order dispensation.
Remember, an adversary (or a sufficiently determined idiot) can quickly expose any flaws in your design.
Footnotes
1Recommended article on cache locality and false sharing in concurrent programming.
written on 13-Jan-2009
chickerino says:
"What happens if two users reach for the same roll simultaneously? We would need some sort of synchronisation mechanism."
WTF??!! Have you been to public restrooms like that?!
written on 15-Jan-2009
asqui says:
Read the paragraph above that sentence: "As specified in assumption 4, we need to be future-proof for the event of a new-age trend for communal toilet paper holders, located at the core of a star-shaped cluster of bathroom stalls. This brings the benefits of increased janitor efficiency and load balancing, but brings about some concurrency challenges."
written on 20-Feb-2009
Maz says:
Let me offer an alternative. Our office has also adopted the A838 in multiple form, although more than likely for different reasons. With fewer staff we have the ability to have a roll each and have adopted a colour coding system. For example, I like a blue roll and my colleague prefers green.
written on 04-Sep-2009
Anonymous says:
Related work: http://blag.xkcd.com/2009/09/02/urinal-protoc ... lity/