Я заинтересован в вычислении последовательности треугольника 1, который является последовательностью пара (i, j): (0, 0), (1, 0), (1, 1), (2, 0), (2, 1) ...
которые итерация, хотя все пары (i, j)
с тем ограничением, что i >= j
. Интересна и такая же последовательность, но с ограничением i> j.Быстро генерирование «последовательность треугольника»: избежать mispredictions
Эти последовательности представляют собой, среди прочих вещей, все способы, чтобы выбрать 2 (возможно, одинаковые) элементы из множества п-элемента (для последовательности по ), или индексы нижних triagular элементов матрица . Последовательность значений только для i
составляет A003056 в OEIS, а j
- A002262. Эта последовательность часто возникает в комбинаторных алгоритмах, где их производительность может быть критической.
Простой, но ветвистый способ генерации следующего значения в последовательности:
if (i == j) {
j = 0;
i++;
} else {
j++;
}
}
Однако, это страдает от многих mispredicts при расчете начальных элементов последовательности, при проверке состояния (i == j)
- целом один неверный прогноз каждый раз, когда i
увеличивается. По мере увеличения последовательности число ошибочных прогнозов становится ниже, так как i
увеличивается с с уменьшенной частотой, поэтому ветвь j++
доминирует и хорошо предсказывается. Тем не менее, некоторые типы комбинаторного поиска многократно перебирают по небольшим терминам в последовательности, поэтому я ищу подход без ветвей или какой-то другой подход, который страдает меньшим количеством ошибочных прогнозов.
Для многих применений порядок последовательностей не так важен, поэтому получение значений в порядке differnet, чем указано выше, является допустимым, если оно приводит к лучшим решениям. Например, j
может рассчитывать, а не вверх: (0, 0), (1, 1), (1, 0), (2, 2), (2, 1), ...
.
Я также заинтересован в зная, что правильное название для этой последовательности (возможно, так что я сделать больше прав на этот вопрос). Я просто вроде «треугольная последовательность».
Здесь, версия i >= j
представляет суб-мультинаборы (повторение разрешено), в то время как i > j
вариант представляет собой нормальные подмножества (нет повторения).
Здесь, версия i >= j
включает в главной диагонали, в то время как i > j
вариант исключает ее.
Почему бы вам просто не развернуть мелкие случаи? И если вы делаете больше, чем несколько инструкций кода приложения с каждой парой, не будет ли это доминирующим? –
Да, на «другой работе может доминировать» точка - но по крайней мере в одном ключевом сценарии объем работы - это всего лишь несколько инструкций, поэтому накладные расходы треугольника являются большой частью. – BeeOnRope
Проблема с разворачиванием заключается в том, что фактический код не находится в цикле (т. Е. С использованием внешней итерации), но вместо этого используется в отступе итератора. Кроме того, предел не является фиксированным, поэтому во время компиляции я не знаю, находится ли я в маленьком n или большом n случае, и даже для разных небольших случаев n требуется разная разворачиваемость. – BeeOnRope