I'm interested in calculating the triangle sequence1, which is the sequence of pairs (i, j): (0, 0), (1, 0), (1, 1), (2, 0), (2, 1) ...
which iterates though all pairs (i, j)
with the restriction that i >= j
. The same sequence with but with the restriction i > j is also interesting.
These sequences represent, among others things, all the ways to choose 2 (possibly identical) elements from a n-element set (for the sequence up to (n, n)
2), or the indices of the lower triagular elements of a matrix3. The sequence of values for i
alone is A003056 in OEIS, while j
alone is A002262. The sequence frequently arises in combinartorial algorithms, where their performance may be critical.
A simple but branchy way to generate the next value in the sequence is:
if (i == j) {
j = 0;
i++;
} else {
j++;
}
}
However, this suffers from many mispredicts while calculating the initial elements of the sequence, when checking the condition (i == j)
-
generally one mispredict each time i
is incremented. As the sequence increases, the number of mispredicts becomes lower since i
is incremented
with reduced frequency, so the j++
branch dominates and is well predicted. Still, some types of combinatorial search repeatedly iterate over the
small terms in the sequence, so I'm looking for a branch-free approach or some other approach that suffers fewer mispredicts.
For many uses, the order of the sequences isn't as important, so generating the values in differnet order than above is a allowable if it leads to
a better solution. For example, j
could count down rather than up: (0, 0), (1, 1), (1, 0), (2, 2), (2, 1), ...
.
1 I'm also interested in knowing what the right name for this sequence is (perhaps so I make a better title for this question). I just kind of made up "triangle sequence".
2 Here, the i >= j
version represents sub-multisets (repetition allowed), while the i > j
variant represents normal subsets (no repetition).
3 Here, the i >= j
version includes the main diagonal, while the i > j
variant excludes it.