Обработка остатка развернутого цикла - PullRequest
2 голосов
/ 15 марта 2012

Добрый день.

Я хотел бы попросить внести вклад в уловки для обработки остатков развернутых циклов с оговоркой, что циклы довольно малы, в 1-3 раза больше коэффициента развертывания, например:

EG. данный коэффициент развертывания B

int i = 0;
for (; i < N-N%B; i += B) {
    ...
}
// remainder
for (; i < N; ++i) {
    ...
}

если B равен 2, я могу сделать следующее:

// remainder
if (N%2) {
    ....
}

Но какой хороший способ справиться B>2

1 Ответ

0 голосов
/ 16 марта 2012

Ваш if (N%2) может быть легко расширен до любого коэффициента развертывания:

for (; i < N-B+1; i += B) {
    x1; x2; ... xB;
}
if (i < N) {
    x1;
if (i < N-1) {
    x2;
    ...
if (i < N-B+2) {
    xB;
}}}

Для небольших коэффициентов развертывания это может быть более эффективным, чем второй цикл или устройство Даффа.

Эта версия выглядитлучше.gcc 4.6 компилирует из него почти тот же код:

if (i++ < N) {
    x1;
if (i++ < N) {
    x2;
    ...
if (i++ < N) {
    xB;
}}}

И эта версия может быть более оптимальной, если B - степень двойки.По крайней мере, gcc компилирует лучший код для него.Кроме того, определенно лучше, если N является константой.Но если ни N не является константой, ни B не является степенью двойки, преимущество этого метода не столь очевидно из-за менее эффективного вычисления остатка (что обычно означает несколько инструкций, включая умножение):

if (N%B > B-2) {
    x1;
if (N%B > B-3) {
    x2;
    ...
if (N%B > 0) {
    xB;
}}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...