Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Разворачивание на C++
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
ReAl
Да вот кстати о С++
Там тема интересная на avrfreaks, мужик хочет добиться нужного разворачивания для скорости вывода. Две страницы многоэтажного ма...кросизма.
Сейчас вот в голову стукнуло «чисто для поржать»
http://www.avrfreaks.net/index.php?name=PN...p=769453#769453
Причём полный улёт — шаблоны, ссылки... Страшный-страшный С++
И результат...
dxp
Цитата(ReAl @ Nov 28 2010, 04:01) *
Да вот кстати о С++
[...]
Причём полный улёт — шаблоны, ссылки... Страшный-страшный С++
И результат...

Посмотрел по ссылке. Красиво. И реализация, и результат. a14.gif
Petka
Цитата(dxp @ Nov 29 2010, 08:20) *
Посмотрел по ссылке. Красиво. И реализация, и результат. a14.gif


bb-offtopic.gif

Можно проще и на чистом си:
Код
inline void unroll_out(uint8_t count, uint8_t value)
{
    PORTB = value;
    value <<= 1;
    if(count) unroll_out(count-1, value);
}

void foo(uint8_t v)
{
    unroll_out(8, v);
}


Результат:
Код
00000014 <foo>:
  14:    88 bb           out    0x18, r24; 24
  16:    88 0f           add    r24, r24
  18:    88 bb           out    0x18, r24; 24
  1a:    88 0f           add    r24, r24
  1c:    88 bb           out    0x18, r24; 24
  1e:    88 0f           add    r24, r24
  20:    88 bb           out    0x18, r24; 24
  22:    88 0f           add    r24, r24
  24:    88 bb           out    0x18, r24; 24
  26:    88 0f           add    r24, r24
  28:    88 bb           out    0x18, r24; 24
  2a:    88 0f           add    r24, r24
  2c:    88 bb           out    0x18, r24; 24
  2e:    88 0f           add    r24, r24
  30:    88 bb           out    0x18, r24; 24
  32:    88 0f           add    r24, r24
  34:    88 bb           out    0x18, r24; 24
  36:    08 95           ret
ReAl
Цитата(Petka @ Nov 29 2010, 09:47) *
bb-offtopic.gif
Можно проще и на чистом си:
Ну так я там ещё вчера и такой вариант привёл.
Только
1) По крайней мере та версия, что у меня (avr-gcc (GCC) 4.3.4), С-шную хвостовую рекурсию при -Os..-O2 только в цикл превращает, но не разворачивает, для разворачивания нужно -O3 или ключами баловаться. А С++-ная на шаблонах при любых ключах копиляции разворачивается в линейный код.
2) И я там, и Вы тут ошибку сделли :-) — выходит восемь сдвигов и девять выводов в порт :-)

p.s. avr-gcc (GCC) 4.6.0 20100525 (experimental) от Klen тоже при -Os..-O2 без unroll-ключей не разврачивает С-шный вариант. С++-ный — при всех уровнях одинаково.
Petka
Цитата(ReAl @ Nov 29 2010, 13:02) *
Ну так я там ещё вчера и такой вариант привёл.

Уже заметил.
Цитата
Только
1) По крайней мере та версия, что у меня (avr-gcc (GCC) 4.3.4), С-шную хвостовую рекурсию при -Os..-O2 только в цикл превращает, но не разворачивает, для разворачивания нужно -O3 или ключами баловаться. А С++-ная на шаблонах при любых ключах копиляции разворачивается в линейный код.

А вот это, кстати, хорошо. Пишешь просто код, который тебе нужен, а если нужна мега оптимизация по скорости просто включаешь её в компиляторе. ИМХО код на шаблонах в этом смысле менее гибок получился.
Цитата
2) И я там, и Вы тут ошибку сделали :-) — выходит восемь сдвигов и девять выводов в порт :-)

Ага. =). Иногда в разные головы приходит одно решение.
P.S.
Тему лучше всё-таки разделить и часть перекинуть в OpenSource раздел.
dxp
Цитата(Petka @ Nov 29 2010, 13:47) *
Можно проще и на чистом си:
Код
inline void unroll_out(uint8_t count, uint8_t value)
{
    PORTB = value;
    value <<= 1;
    if(count) unroll_out(count-1, value);
}

void foo(uint8_t v)
{
    unroll_out(8, v);
}

Есть принципиальная разница: шаблонный вариант всегда разворачивается на этапе компиляции, а сишный содержит рантаймное условие. И тут уже от компилятора зависит, развернет или нет.

Цитата(Petka @ Nov 29 2010, 16:34) *
А вот это, кстати, хорошо. Пишешь просто код, который тебе нужен, а если нужна мега оптимизация по скорости просто включаешь её в компиляторе.

Вот ничего хорошего тут нет - поведение непредсказуемое, зависящее от ключей компилятора, от сборки, от версии и ещё бог знает от чего.

Цитата(Petka @ Nov 29 2010, 16:34) *
ИМХО код на шаблонах в этом смысле менее гибок получился.

Код на шаблонах получается предсказуемым с гарантированным поведением. Если мне нужен именно unroll, то я его и применяю. И ожидаю, что это будет именно разворачивание. Если мне не нужно разворачивать, то не применяю это. Согласитесь, что вызывать функцию unroll, которая не делает unroll, как-то странно.
ReAl
По шаблонам — там на avrfreaks меня, я считаю, вполне оправданно поправили.
Для шаблонов ниакой рекурсии нет, есть разные функции (сгенерированные из одного шаблона), которые вызывают по цепочке друг друга. Потому и код не зависит от типа оптимизации.

А что процесс генерации функций (осознание необходимости сгенерировать очередную) происходит рекурсивно, так это на этапе компиляции :-)
Т.е. шаблон-то рекурсивный, но он не порождает рекурсивный код.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.