Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Развернуть цикл, GCC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Qwertty
Нужно развернуть цикл принудительно. Опция -O3 эффекта не дала. Документация посоветовала -funroll-all-loops, но тоже не сработало. laughing.gif
Какое заклинание нужно применять?
klen
для начала он должен быть разворачивыймым
тоесть число итерацй известно на этапе компиляции
иначе непонятно сколько его разворачивать
ReAl
Цитата(klen @ Dec 23 2009, 20:59) *
для начала он должен быть разворачивыймым
тоесть число итерацй известно на этапе компиляции иначе непонятно сколько его разворачивать
Да если захочет, то и такие разворачивает. Берёт какое-то число операций для тела - чтобы не одну, сначала выбирает остаток, потом гонит цикл с этим числом.

Код
extern unsigned arr[];

void foo(unsigned cnt)
{
    unsigned i;
    for(i=0;i<cnt;++i)
        arr[i] = i;
}

gcc -O3 -funroll-all-loops
Код
    .file    "c.c"
    .text
    .p2align 4,,15
.globl _foo
    .def    _foo;    .scl    2;    .type    32;    .endef
_foo:
    pushl    %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %ecx
    testl    %ecx, %ecx
    je    L7
    xorl    %edx, %edx
    leal    -1(%ecx), %eax
    andl    $7, %eax
    movl    %edx, _arr
    movl    $1, %edx
    cmpl    %ecx, %edx
    jae    L7
    testl    %eax, %eax
    je    L8
    cmpl    $1, %eax
    je    L35
    cmpl    $2, %eax
    je    L36
    cmpl    $3, %eax
    je    L37
    cmpl    $4, %eax
    je    L38
    cmpl    $5, %eax
    je    L39
    cmpl    $6, %eax
    je    L40
    movl    $1, %eax
    movl    $2, %edx
    movl    %eax, _arr+4
L40:
    movl    %edx, _arr(,%edx,4)
    incl    %edx
L39:
    movl    %edx, _arr(,%edx,4)
    incl    %edx
L38:
    movl    %edx, _arr(,%edx,4)
    incl    %edx
L37:
    movl    %edx, _arr(,%edx,4)
    incl    %edx
L36:
    movl    %edx, _arr(,%edx,4)
    incl    %edx
L35:
    movl    %edx, _arr(,%edx,4)
    incl    %edx
    cmpl    %ecx, %edx
    jae    L7
L8:
    movl    %edx, _arr(,%edx,4)
    leal    1(%edx), %eax
    movl    %eax, _arr(,%eax,4)
    leal    2(%edx), %eax
    movl    %eax, _arr(,%eax,4)
    leal    3(%edx), %eax
    movl    %eax, _arr(,%eax,4)
    leal    4(%edx), %eax
    movl    %eax, _arr(,%eax,4)
    leal    5(%edx), %eax
    movl    %eax, _arr(,%eax,4)
    leal    6(%edx), %eax
    movl    %eax, _arr(,%eax,4)
    leal    7(%edx), %eax
    addl    $8, %edx
    movl    %eax, _arr(,%eax,4)
    cmpl    %ecx, %edx
    jb    L8
L7:
    popl    %ebp
    ret
Qwertty
Цитата(klen @ Dec 23 2009, 21:59) *
тоесть число итерацй известно на этапе компиляции

Оно известно. Я на простейшей функции тестирую.
Код
void TestUnroll(unsigned char* ptr1, unsigned char* ptr2)
{
unsigned int i;
  for(i = 0; i <100; i++) *ptr2++ = *ptr1++;
}

Получил с -O3 и -funroll-all-loops
Код
void TestUnroll(unsigned char* ptr1, unsigned char* ptr2)
{
       E92D4010   stmfd sp!, {r4, lr}
{
       E1A0C001   mov r12, r1
       E1A0E000   mov lr, r0
       E3A04000   mov r4, #0x00000000
unsigned int i;
  for(i = 0; i <100; i++) *ptr2++ = *ptr1++;
       E1A0000E   mov r0, lr
       E4D03001   ldrb r3, [r0], #+0x001
       E1A0100C   mov r1, r12
       E4C13001   strb r3, [r1], #+0x001
       E5DE2001   ldrb r2, [lr, #+0x001]
       E5CC2001   strb r2, [r12, #+0x001]
       E5D03001   ldrb r3, [r0, #+0x001]
       E5C13001   strb r3, [r1, #+0x001]
       E5DE0003   ldrb r0, [lr, #+0x003]
       E5CC0003   strb r0, [r12, #+0x003]
       E5DE2004   ldrb r2, [lr, #+0x004]
       E5CC2004   strb r2, [r12, #+0x004]
       E5DE3005   ldrb r3, [lr, #+0x005]
       E5CC3005   strb r3, [r12, #+0x005]
       E5DE1006   ldrb r1, [lr, #+0x006]
       E5CC1006   strb r1, [r12, #+0x006]
       E5DE0007   ldrb r0, [lr, #+0x007]
       E5CC0007   strb r0, [r12, #+0x007]
       E5DE2008   ldrb r2, [lr, #+0x008]
       E5CC2008   strb r2, [r12, #+0x008]
       E284400A   add r4, r4, #0x0000000A
       E5DE3009   ldrb r3, [lr, #+0x009]
       E3540064   cmp r4, #0x00000064
       E5CC3009   strb r3, [r12, #+0x009]
       E28EE00A   add lr, lr, #0x0000000A
       E28CC00A   add r12, r12, #0x0000000A
       1AFFFFE4   bne 0x000002C0
       E8BD8010   ldmfd sp!, {r4, pc}

Я видимо не правильно вопрос задал потому как циклы все же разворачивает, но частично - 100 итераций превращаются в 10 по 10. Сразу в 100 не хочет.
Где то это ограничение задается?
MrYuran
Цитата(Qwertty @ Dec 24 2009, 09:21) *
Я видимо не правильно вопрос задал потому как циклы все же разворачивает, но частично - 100 итераций превращаются в 10 по 10. Сразу в 100 не хочет.
Где то это ограничение задается?

Видимо, исходит из здравого смысла.
Разворачивает, но без фанатизма.
Vova75
Цитата(Qwertty @ Dec 24 2009, 09:21) *
Я видимо не правильно вопрос задал потому как циклы все же разворачивает, но частично - 100 итераций превращаются в 10 по 10. Сразу в 100 не хочет.
Где то это ограничение задается?


Если подходить к делу с фанатизмом  то это поможет:
--param max-unrolled-insns=5000
--param max-average-unrolled-insns=5000
--param max-unroll-times=500
Но результат будет более чем экстремальный.
Qwertty
Цитата(Vova75 @ Jan 26 2010, 19:43) *
Если подходить к делу с фанатизмом  то это поможет:

Спасибо! Давно не заглядывал, а тут оказывается решение есть.
Гугл по этим ключикам много интересного находит...
dch
как помогло unroll ?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.