Counting

A filter that reads the word it saves

A selection sort's record of adjacent order, two bits a neighbouring pair, costs 1.09 word reads a question and spends 201 of them for every comparison it saves on 1,024 keys in short runs, because it is asked everything and answers almost nothing. A filter bit beside each pair, set only where a run could start, was predicted to turn away three quarters of the questions and cut that price to under sixty. It turns away two thirds and cuts the price to 185. The questions it turns away were already refused in the first word, the filter is read in that same word, and one read a question is a floor no filter can go under.

What it costs to consult two bits a pair priced a record that had been counted as free. The two-ended selection sort scans for the smallest and largest keys left and swaps them to the ends, and a pass repaid by the scans after it gave it a pass first that compares every key with the next, so that a record of two bits a neighbouring pair holds which way each pair points. A question about positions i<ji < j is answered without a comparison when every pair from ii to j−1j - 1 points the same way. Read sixteen pairs to a 32-bit word, the record cost 1.09 words a question on 1,024 keys in runs of four, and its reading stops at the first pair that breaks the run, so almost every question costs one word. The price that mattered was the other number: 201 word reads for every comparison the record saved, because it saves a comparison on about one question in two hundred.

Its closing section looked for a way to ask less. The record can say, before any of its words is read past the first, where it has nothing to offer: a position whose pair to the right is unknown, or whose run turns at that position, cannot start an answer about any position two or more to its right. A sort could keep one more bit a position, set when the pair there is known and the next pair points the same way, and consult the rest of the record only when that bit is set at the question’s first position. The bit would sit in the same word as the pair. The prediction was that on runs of four keys it would turn away about three quarters of the questions, and that the price a saved comparison would fall by about that factor, to under sixty word reads at 1,024 keys. It named the risk that the sort’s questions are asked from its current extreme, and that the extreme might sit mid-run more often than a random position does.

The filter turns away nearly as many questions as predicted. The price barely moves, and the reason was in the earlier essay’s first number all along.

A bit that says where a run can start

The sort, the inputs and the pass are the earlier essay’s: the two-ended selection sort with its pass between neighbours and its two chains of past minima and maxima consulted first, on 256, 1,024 and 4,096 keys cut into sorted runs of 4 keys up to the whole array, the runs’ values interleaving at random. Every question the sort puts to its record of adjacent order is charged three ways at once, and none of them changes the sort or its answers, which are still checked against the keys.

The record of two bits a pair is charged as before: the words from the one holding the pair at ii to the one holding the last pair examined. The run list, which keeps even the runs too short to drop, is charged its binary-search probes. Behind the filter, a question about positions two or more apart reads the word holding the pair at ii, finds the filter bit beside it, and is turned away at that one word if the bit is clear, meaning the pair at ii is unknown or the pair at i+1i + 1 points the other way. If the bit is set, the question reads on as the plain record would. A question about two neighbours needs only the pair at ii and reads that one word in every scheme. The filter bit is never clear for a question the record could answer, since any answer needs the pairs at ii and i+1i + 1 to point one way.

Two thirds turned away, one word each

On 1,024 keys in runs of four, a filter bit beside each pair turns away 66% of the questions put to the record and brings the words it reads from 1.094 a question to 1.007: the questions it turns away were already answered in the first word, and one word a question is a floor the filter cannot go belowThe two-ended selection sort with its pass first, on 1,024 keys in sorted runs of 4 keys to the whole array: the 32-bit words the record of two bits a pair reads a question, the same behind a filter bit read in the first word, and the binary-search probes of the run list. runs of 4: bits 1.094, filtered 1.007 (66% turned away), list 8.80; runs of 8: bits 1.119, filtered 1.006 (61% turned away), list 8.01; runs of 16: bits 1.141, filtered 1.001 (62% turned away), list 7.07; runs of 32: bits 1.425, filtered 1.350 (62% turned away), list 6.28; runs of 64: bits 1.901, filtered 1.844 (63% turned away), list 5.74; runs of 128: bits 2.769, filtered 2.726 (62% turned away), list 4.96; runs of 256: bits 4.204, filtered 4.175 (57% turned away), list 4.71; runs of 512: bits 5.852, filtered 5.825 (54% turned away), list 4.51; runs of sorted: bits 22.132, filtered 22.132 (0% turned away), list 2.00.0124816keys in each sorted run of the inputreads a question: words, or probes of the list48163264128256512sortedone word: the word that holds the first pairrun list, probestwo bits a pair, wordsbehind the filter, words1,024 keys, a pass firstsorted array cut at 24
Fig. 1 Reads a question on 1,024 keys, against the length of the input’s sorted runs. Two bits a pair: 1.094 words on runs of four, 1.141 on runs of sixteen, 4.204 on runs of 256, 22.13 on a sorted array. Behind the filter: 1.007, 1.001, 4.175 and 22.13. The run list: 8.80, 7.07, 4.71 and 2.00 probes. The rule at one word marks the word that holds the first pair.

On 1,024 keys in runs of four, the filter turns away 66% of the questions put to the record and brings the words read from 1.094 a question to 1.007. On runs of sixteen it brings them from 1.141 to 1.001. The two curves are one curve at the scale of the plate, and so is the curve of the run list’s probes they were measured against: the list is still 8.80 probes a question on short runs and still becomes the cheaper record only on runs of 512 keys.

The same holds at every size. Behind the filter the record reads 1.008 words a question at 256 keys, 1.007 at 1,024 and 1.006 at 4,096 on runs of four, against 1.060, 1.094 and 1.074 without it: whatever the size, the filter takes the reading to within a hundredth of a word of one, and the size of the input changes nothing about that one.

A question the record cannot answer was already cheap. It reads the word holding the pair at ii, finds that pair unknown or the next one turning, and stops, all inside that word unless the pair at ii is the last of its word. The filter reads the same word and stops in the same place. What it saves is the second word, read only when the break falls just across a word boundary, which happens to about one turned-away question in eight. The rest of what the record reads beyond its first word is the scan across an answer, and an answer is exactly what the filter lets through.

Close to the three quarters predicted

The filter turns away 54% to 67% of the record's questions at every size and run length, close to the three quarters predicted; but of the questions it turns away at 1,024 keys in runs of four, only 13% would have cost the record more than the one word the filter itself readsAt 256, 1,024 and 4,096 keys, against run length (sorted arrays left out, where the filter turns nothing away): the share of questions the filter turns away (solid), and the share that it turns away and that the record of two bits a pair would have read more than one word to refuse (dotted). 256 keys: 4 61% and 5.2%, 8 57% and 10.8%, 16 58% and 11.8%, 32 55% and 5.4%, 64 59% and 3.5%, 128 54% and 1.5%. 1,024 keys: 4 66% and 8.7%, 8 61% and 11.3%, 16 62% and 13.9%, 32 62% and 7.5%, 64 63% and 5.7%, 128 62% and 4.3%, 256 57% and 2.9%, 512 54% and 2.7%. 4,096 keys: 4 67% and 6.8%, 8 63% and 12.2%, 16 64% and 14.7%, 32 65% and 7.9%, 64 65% and 5.6%, 128 66% and 5.2%, 256 65% and 4.9%, 512 64% and 3.9%, 1024 61% and 3.3%, 2048 56% and 3.0%.00.2000.4000.6000.800keys in each sorted run of the inputshare of the record's questions4816326412825651210242048256 keys1,024 keys4,096 keysdotted: turned away and deara pass firstshare of all questions
Fig. 2 The share of the record’s questions the filter turns away, at 256, 1,024 and 4,096 keys against run length (solid), and the share it turns away that would have cost the record more than a word (dotted). Runs of four: 61%, 66% and 67% turned away; 5.2%, 8.7% and 6.8% dear. Runs of 512 at 1,024 keys: 54% and 2.7%.

The filter turns away 54% to 67% of the record’s questions at every size and every run length short of a sorted array, and at 1,024 keys in runs of four only 13% of the questions it turns away would have cost the record more than the one word the filter reads. The prediction’s three quarters is close. Its reasoning, that a run of four has a pair pointing the same way after only half its positions, is the right kind of reasoning about where runs start. The risk it named, that the current extreme sits mid-run more often than a random position, does not materialise; the extreme turns the run at its own position about as often as the share suggests.

The share is nearly flat in run length because a question’s first position is the sort’s current minimum or maximum, and an extreme of what is left is, by construction, a place where the order turns: the key after a minimum is larger, and on interleaved runs the key after that is often smaller again. Long runs raise the chance that the next pair points the same way, but the extremes of the unsorted remainder are mostly at the turns between runs, so even on runs of 512 keys more than half the questions start where nothing can be answered.

The reading beyond the first word

Of the words the record reads beyond the first on 1,024 keys in runs of four, 0.094 a question, the filter removes 92%; on longer runs the reading beyond the first word is the scan across an answer, and the filter removes 1% of it on runs of 512On 1,024 keys, for each run length: the words a question the record of two bits a pair reads beyond the first, and the same behind the filter. runs of 4: 0.094 and 0.007; runs of 8: 0.119 and 0.006; runs of 16: 0.141 and 0.001; runs of 32: 0.425 and 0.350; runs of 64: 0.901 and 0.844; runs of 128: 1.769 and 1.726; runs of 256: 3.204 and 3.175; runs of 512: 4.852 and 4.825.two bits a pairbehind the filter01234runs of 4runs of 8runs of 16runs of 32runs of 64runs of 128runs of 256runs of 512words a question beyond the first1,024 keys, a pass firstthe first word is paid either way
Fig. 3 On 1,024 keys, the words a question the record reads beyond the first, plain and behind the filter. Runs of four: 0.094 and 0.007. Runs of sixteen: 0.141 and 0.001. Runs of 64: 0.90 and 0.84. Runs of 512: 4.85 and 4.83.

Of the 0.094 words a question the record reads beyond the first on 1,024 keys in runs of four, the filter removes 92%; on runs of 512 keys it removes 1% of the 4.85. On short runs the reading beyond the first word is almost all wasted reading of turned-away questions that straddle a word boundary, and the filter takes nearly all of it. On long runs it is the reading of answers, the scan from ii to j−1j - 1 across a run that holds them both, and the filter is designed never to stop that.

Between those two ends the share the filter removes falls steadily: on runs of 32 keys the record reads 0.425 words a question beyond the first and the filter 0.350, and on runs of 128 the record reads 1.77 and the filter 1.73. As runs lengthen, more of the questions the sort asks are about positions inside one run, the record answers more of them, and answering is reading.

So the filter works exactly as designed and has almost nothing to work on. The plain record’s 1.094 words a question is one word a question plus 0.094, and only the 0.094 was ever in reach. The one word is the price of reading the record at all, and the filter is read in it.

A price made of questions

Behind the filter the record still spends 185 word reads for every comparison it saves on 1,024 keys in runs of four, against 201 without it, and 716 against 764 at 4,096 keys — not the predicted sixty: the price is the questions asked, and the filter still reads a word for every oneWord reads a saved comparison — the record's words over all its questions, divided by the comparisons it removes from the sort — with and without the filter (dashed), at 256, 1,024 and 4,096 keys on runs of 4 to 64 keys. 256 keys: 4 48.35 and 45.96, 8 30.50 and 27.55, 16 18.27 and 16.36, 32 11.47 and 11.03, 64 8.22 and 8.05. 1,024 keys: 4 201.42 and 185.38, 8 118.06 and 106.12, 16 66.23 and 58.14, 32 42.58 and 40.35, 64 30.81 and 29.89. 4,096 keys: 4 763.89 and 715.77, 8 473.90 and 422.62, 16 264.98 and 231.13, 32 173.76 and 164.06, 64 122.27 and 118.77.keys in each sorted run of the inputword reads for each comparison saved (log scale)14166425648163264256 keys1,024 keys4,096 keysdashed: behind the filtera pass firstlogarithmic scale
Fig. 4 Word reads for each comparison the record saves, plain (solid) and behind the filter (dashed), at three sizes on runs of 4 to 64 keys. At 1,024 keys: 201 and 185 on runs of four, 66 and 58 on runs of sixteen, 31 and 30 on runs of 64. At 4,096 keys: 764 and 716 on runs of four. At 256 keys: 48 and 46.

Behind the filter the record spends 185 word reads for every comparison it saves on 1,024 keys in runs of four, against 201 without it, and 716 against 764 at 4,096 keys: an eighth of the predicted fall. The prediction expected the price to fall with the questions turned away. It falls with the words saved, and the turned-away questions still cost one word each.

The record is asked 184 questions for every comparison it saves on 1,024 keys in runs of four and 711 at 4,096 keys, and any record that is read at least once a question pays at least that many reads a saving; on runs of 256 keys the ratio falls to 4.34Questions the sort puts to its record of adjacent order for each comparison the record removes, at 256, 1,024 and 4,096 keys, against run length. 256 keys: 4 45.61 (17,559 questions, 385 saved), 8 27.31 (17,698 questions, 648 saved), 16 16.22 (18,066 questions, 1,114 saved), 32 8.22 (18,816 questions, 2,289 saved), 64 4.71 (19,649 questions, 4,168 saved), 128 2.81 (24,148 questions, 8,595 saved). 1,024 keys: 4 184.03 (264,639 questions, 1,438 saved), 8 105.47 (266,634 questions, 2,528 saved), 16 58.07 (269,778 questions, 4,646 saved), 32 29.88 (268,965 questions, 9,002 saved), 64 16.21 (277,168 questions, 17,100 saved), 128 8.33 (285,267 questions, 34,253 saved), 256 4.34 (297,794 questions, 68,596 saved), 512 2.74 (379,817 questions, 138,827 saved). 4,096 keys: 4 711.48 (4,251,793 questions, 5,976 saved), 8 420.63 (4,246,229 questions, 10,095 saved), 16 230.29 (4,232,063 questions, 18,377 saved), 32 122.37 (4,274,303 questions, 34,930 saved), 64 62.44 (4,260,666 questions, 68,240 saved), 128 32.00 (4,300,489 questions, 134,387 saved), 256 16.33 (4,358,163 questions, 266,885 saved), 512 8.40 (4,504,890 questions, 536,340 saved), 1024 4.43 (4,827,999 questions, 1,090,594 saved), 2048 2.81 (6,074,321 questions, 2,164,778 saved).keys in each sorted run of the inputquestions asked for each comparison saved (log scale)1416642564816326412825651210242048256 keys1,024 keys4,096 keysa pass firstlogarithmic scale
Fig. 5 Questions the sort puts to its record for each comparison the record saves, at three sizes against run length. Runs of four: 46 at 256 keys, 184 at 1,024, 711 at 4,096. Runs of sixteen at 1,024 keys: 58. Runs of 256: 4.34. Runs of 2,048 at 4,096 keys: 2.81.

The record is asked 184 questions for every comparison it saves on 1,024 keys in runs of four, and 711 at 4,096 keys. That ratio is the floor under every scheme in which the record is read at least once a question. The plain record pays 1.094 words a question and so 201 a saving; the filter pays 1.007 and so 185; a perfect filter that read exactly one word and never more would pay 184. On runs of four keys the price is set by how often the sort asks, not by how much each answer reads.

The ratio grows with the input because the questions do and the savings do not. The two-ended selection sort asks about n2/4n^2/4 questions in all, one for every key in every scan, and the record saves comparisons only where runs survive the swaps, about nn of them on short runs, a few per scan. Doubling nn quadruples the questions and doubles the savings. On long runs the record answers a quarter or a third of the questions and the ratio falls to three or four; there the price is set by the length of the answers, and a filter has nothing to remove.

The record a filter would help

There is one record on these plates whose cost a filter would cut, and it is not the one the filter was designed for. The run list pays its binary search on every question, answerable or not, because the search is how it finds out whether a run holds the first position at all. A filter bitmap in front of it, one bit a position read in one word, would spare the search on every question it turns away. On 1,024 keys in runs of four, with two thirds of the questions turned away at one word and the other third paying the list’s 8.8 probes, that is about 3.6 reads a question by arithmetic from the measured shares, not a measurement. It is still more than three times what the plain bits cost. The filter makes the expensive record less expensive and leaves the cheap record where it was, because the cheap record was already a filter: its first word answers the filter’s question.

Where the cost of a record really lies

The earlier essay found that the run list’s search grows with the runs it holds and the bit record’s does not, and concluded that the bits are cheap and the list is not. Measured in reads a question, that is right, and it is the same lesson the record measured where it would run taught about a table of pairs. Measured in reads a saving, both records are expensive on short runs for one reason: the sort asks a record about every key of every scan, and on short runs almost none of those questions can be answered. The questions a sort asks twice measured how often a sort repeats itself; the record answers far less often than that, because answering needs a run between the two positions, not just a past comparison of them.

A filter is a cheaper record of the same fact the record already holds in its first word, so it cannot reduce the number of times that fact has to be read. Something that is read less often than once a question would have to live somewhere the sort reads for nothing. The sort keeps its current minimum and maximum in registers, and every question it asks starts from one of them. That is the place to put what a record knows about where the run from the extreme ends.

The price of remembering an answer put the break-even for a table of compared pairs at three reads a saving. Every scheme on these plates is above that on short runs, by a factor of fifteen at 256 keys and of two hundred and forty at 4,096. On runs of 64 keys or more the record comes within a factor of ten of it at 1,024 keys, and on runs of 256 keys it is at 18.

What the prediction got right

The closing section predicted that on runs of four keys the filter would turn away about three quarters of the questions. It turns away 66% at 1,024 keys, and 61% to 67% at the other sizes. It predicted that the price per saved comparison would fall by about that factor, to under sixty word reads at 1,024 keys. It falls from 201 to 185, because the questions turned away had cost one word each and still do: the filter bit lives in the word the question reads first.

It named a failure, that the questions a selection sort asks are by their nature about the places where order has just been broken, so that the filter would let through as many as before. That failure does not occur, since the filter does turn away two thirds of the questions, and its premise is right in another sense: the questions are mostly about places where no run can answer, which is why a record read once a question is expensive however it is read. The question the section asked, whether a record can learn where it is useful from its own shape, has a narrow answer. It can, and the shape it learns from is already in the word it reads first.

What the counts assume

Words, not time. A word read is one unit whether it is in cache or not. The record of 1,024 keys is 64 words and lives in one or two cache lines’ worth of the first level for the whole sort, so a real machine would charge its reads less than a comparison of two keys in memory. Nothing was timed.

One input shape. Runs of a fixed length with interleaved values. Inputs whose runs vary in length, or whose runs are nested, would give a different share of answerable questions; the earlier essays used this shape throughout, and so does this one.

The filter in the same word. The filter bit is charged nothing beyond the word that holds the pair. Kept in a separate bitmap it would cost a second word on every question it lets through and save nothing on the ones it turns away, so the plates show the filter at its cheapest.

Still open: a run end kept in a register

Every question the sort asks starts from its current minimum or its current maximum, two positions it already keeps in registers, and it asks hundreds of questions from each before either changes. The record’s answer to all of them depends on one number: how far the run starting at that position reaches. A sort could find that number once, by scanning the record from the extreme to the run’s first break, keep it in a register beside the extreme, and answer every later question from that position by one comparison of jj with the register, reading no word at all. The register must be refreshed when the extreme moves or when a pair inside its run changes.

The measurement that follows gives the sort two such registers and charges the scans that fill them. The prediction is that on runs of four keys the reads fall from about one word a question to about one word for every change of extreme, so that the price per saved comparison falls from 185 to under ten at 1,024 keys and stops growing with nn, because the extremes change about as often as the record saves a comparison. It could fail on long runs. A run that spans much of the array is broken at its ends by every pass’s two swaps, and each break forces a rescan of the whole run, so on long runs the register may read more than the plain record does. The question is whether the cost of consulting a record belongs to the questions or to the moments when what the record knows about the question’s first position changes.

What this makes readable

Essays that name this one as a prerequisite.

Named alongside this one

Essays reaching for the same objects. Nobody chose these; they are what the concept index makes visible.

What links here

Every essay whose body links to this one.

The objects this essay names

Each one links to every other essay that touches it.

Bit vectorComparison countNatural runPredictionSelection sortSpace time trade