|
|
  |
Разворачивание на C++ |
|
|
|
Nov 27 2010, 22:01
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Да вот кстати о С++ Там тема интересная на avrfreaks, мужик хочет добиться нужного разворачивания для скорости вывода. Две страницы многоэтажного ма...кросизма. Сейчас вот в голову стукнуло «чисто для поржать» http://www.avrfreaks.net/index.php?name=PN...p=769453#769453Причём полный улёт — шаблоны, ссылки... Страшный-страшный С++ И результат...
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 29 2010, 07:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(dxp @ Nov 29 2010, 08:20)  Посмотрел по ссылке. Красиво. И реализация, и результат.  Можно проще и на чистом си: Код 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
|
|
|
|
|
Nov 29 2010, 10:02
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Petka @ Nov 29 2010, 09:47)  Можно проще и на чистом си: Ну так я там ещё вчера и такой вариант привёл. Только 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-ключей не разврачивает С-шный вариант. С++-ный — при всех уровнях одинаково.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 29 2010, 10:34
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(ReAl @ Nov 29 2010, 13:02)  Ну так я там ещё вчера и такой вариант привёл. Уже заметил. Цитата Только 1) По крайней мере та версия, что у меня (avr-gcc (GCC) 4.3.4), С-шную хвостовую рекурсию при -Os..-O2 только в цикл превращает, но не разворачивает, для разворачивания нужно -O3 или ключами баловаться. А С++-ная на шаблонах при любых ключах копиляции разворачивается в линейный код. А вот это, кстати, хорошо. Пишешь просто код, который тебе нужен, а если нужна мега оптимизация по скорости просто включаешь её в компиляторе. ИМХО код на шаблонах в этом смысле менее гибок получился. Цитата 2) И я там, и Вы тут ошибку сделали :-) — выходит восемь сдвигов и девять выводов в порт :-) Ага. =). Иногда в разные головы приходит одно решение. P.S. Тему лучше всё-таки разделить и часть перекинуть в OpenSource раздел.
|
|
|
|
|
Nov 30 2010, 06:11
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(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, как-то странно.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Nov 30 2010, 21:55
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
По шаблонам — там на avrfreaks меня, я считаю, вполне оправданно поправили. Для шаблонов ниакой рекурсии нет, есть разные функции (сгенерированные из одного шаблона), которые вызывают по цепочке друг друга. Потому и код не зависит от типа оптимизации. А что процесс генерации функций (осознание необходимости сгенерировать очередную) происходит рекурсивно, так это на этапе компиляции :-) Т.е. шаблон-то рекурсивный, но он не порождает рекурсивный код.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|