#опытным
Мы можем конечно и сами разворачивать циклы, но код будет повторяться и от этого потенциально много проблем будет.
Ну хорошо, у нас есть все инструменты, чтобы явно не повторять код. Например вот так:
template <typename F, std::size_t... Is>
void repeat_unrolled_impl(F&& f, std::index_sequence<Is...>)
{
((f(), void(Is)), ...);
}
template <std::size_t Iterations, typename F>
void repeat_unrolled(F&& f)
{
repeat_unrolled_impl(std::forward<F>(f),
std::make_index_sequence<Iterations>{});
}
volatile int i = 0;
int main()
{
repeat_unrolled<6>([&]{ ++i; });
}
Определяем парочку шаблонных функций, которые с помощью std::index_sequence и fold expression полностью изничтожают цикл и просто подряд вызывают функтор столько раз, сколько вы указали в шаблонном параметре repeat_unrolled.
Асм можете посмотреть тут. Здесь конечно есть одна хитрость с volatile, чтобы компилятор не соптимизировал наши тривиальные вычисления, но тем не менее.
Хотите частичную развертку? Да пожалуйста:
template <typename F, std::size_t... Offsets>
void call_with_offsets(F&& f, std::index_sequence<Offsets...>) {
((f(), void(Offsets)), ...);
}
template <std::size_t Iterations, std::size_t UnrollFactor, typename F>
void partial_unroll(F&& f) {
constexpr std::size_t full_blocks = Iterations / UnrollFactor;
constexpr std::size_t remainder = Iterations % UnrollFactor;
for (std::size_t block = 0; block < full_blocks; ++block) {
call_with_offsets(std::forward<F>(f),
std::make_index_sequence<UnrollFactor>{});
}
for (std::size_t i = 0; i < remainder; ++i) {
f();
}
}
volatile int counter = 0;
int main() {
partial_unroll<101, 4>([&]{ ++counter; });
}
Приемы используются те же, развертку тоже можете сами увидеть.
Зачем этот пост? Да просто наткнулся на такой код при подготовке к этой серии статей. Удивился, что в нескольких источниках упоминается такой способ и решил поделиться. Не знаю на счет применимости такого кода, выглядит сомнительно и не во всех ситуациях подойдет.
Но по крайней мере где-нибудь на собеседовании можно задать такую задачку на шаблоны. И прикладной смысл понятен и не особо сложно как будто бы.
Use templates in the right place. Stay cool.
#template #interview