Переход на IDE 1.8.8 Тормоза в обработчике прерывания?

Logik
Offline
Зарегистрирован: 05.08.2014

Перевожу старые проекты в IDE 1.8.8. Вобщем все как обычно - мелкие правки и работает. Все, за исключением одного проекта. Его скорость работы катастрофически упала. Оцениваю на глаз, по FPS на экране, ранее все динамично прорисовывалось 5-7FPS получалось, а теперь секунд 10 перерисовывает кадр. Специфика проекта - высокая загрузка прерывания таймера, делитель 256 т.е. частота 62,5КГц. Настраиваю так.

  TIMSK1|=1; //TOIE1
  
 /* clear OC1A on Compare Match, set OC1A at TOP */
 TCCR1A =   _BV(COM1A1); 
 /* fast PWM, 8 bit */
 TCCR1A |=  _BV(WGM10);
 TCCR1B = _BV(WGM12) ;
 /* no prescaling */
 TCCR1B |= _BV(CS10) ;

Обработчик цепляю как ISR(TIMER1_OVF_vect) 

 

В IDE 1.0.6 и IDE 1.6.5 никаких проблем не возникало. 

Решил проверить, закоментировать пару строк в обработчике - проект зашевелился. Получается обработчик в новом IDE исполняется медленей чем в старых 8\  В обработчике ниче тяжелого нет - ввод с АЦП напрямую, сохранение введеного в массив,  табличная генерация отсчета синусоиды и вывод его ШИМ-ом. 

Никто с таким не сталкивался?

Может сохранение/восстановление регистров "утяжелили" или оптимизация чудит..

Green
Offline
Зарегистрирован: 01.10.2015

) Пролог/эпилог посмотреть (сравнить) ведь можно.

Logik
Offline
Зарегистрирован: 05.08.2014

какраз смотрю

0000251e <__vector_13>:
    251e:	1f 92       	push	r1
    2520:	0f 92       	push	r0
    2522:	0f b6       	in	r0, 0x3f	; 63
    2524:	0f 92       	push	r0
    2526:	11 24       	eor	r1, r1
    2528:	2f 93       	push	r18
    252a:	3f 93       	push	r19
    252c:	4f 93       	push	r20
    252e:	5f 93       	push	r21
    2530:	6f 93       	push	r22
    2532:	7f 93       	push	r23
    2534:	8f 93       	push	r24
    2536:	9f 93       	push	r25
    2538:	af 93       	push	r26
    253a:	bf 93       	push	r27
    253c:	cf 93       	push	r28
    253e:	df 93       	push	r29
    2540:	ef 93       	push	r30
    2542:	ff 93       	push	r31

r30, r31 явно лишние. эпилог понятно тоже но в обратную.

Проблема в том что старых ИДЕ уже нет под рукой, сравнивать не с чем. И особо зарыватся в тему не охота. Бля, от из за такого и ненавижу апдейтить софт..

ПС. не r30, r31 как потом заметил по делу сохранило.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Logik, видимо оптимизация другая. Про "ничего тяжёлого нет" -хорошая шутка :)  При больших вычислениях только что-б в стек сбекапить/восстановить все регистры нужно 32x2x2=128 тактов =8µS  А при частоте прерываний 62500 раз/сек  на прерывание будет приходиться максимум 16µS. Тоесть на всё про всё у нас максимум остаётся ещё 128 тактов мк. :-\  ps: (если конечно ничего не напутал, я могу:)

Logik
Offline
Зарегистрирован: 05.08.2014

Чето както табличная генерация синуса не компактно выглядит. Исходник

signed char TabSin(unsigned char x)
{
const byte TabSin[64]={0, 3,  6,  9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49,
                       51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90,
                       92, 94, 96, 98,100,102,104,106,107,109,111,112,113,115,116,117,
                      118,120,121,122,122,123,124,125,125,126,126,126,127,127,127};

signed char r=TabSin[((x&0x40)?-x-1:x)&0x3f];
 if(x&0x80)
   return -r;
 return r;
 }

Собрало в

00001930 <_Z6TabSinh>:
    1930:	cf 93       	push	r28
    1932:	df 93       	push	r29
    1934:	cd b7       	in	r28, 0x3d	; 61
    1936:	de b7       	in	r29, 0x3e	; 62
    1938:	c0 54       	subi	r28, 0x40	; 64
    193a:	d1 09       	sbc	r29, r1
    193c:	0f b6       	in	r0, 0x3f	; 63
    193e:	f8 94       	cli
    1940:	de bf       	out	0x3e, r29	; 62
    1942:	0f be       	out	0x3f, r0	; 63
    1944:	cd bf       	out	0x3d, r28	; 61
    1946:	98 2f       	mov	r25, r24
    1948:	80 e4       	ldi	r24, 0x40	; 64
    194a:	e7 e0       	ldi	r30, 0x07	; 7
    194c:	f1 e0       	ldi	r31, 0x01	; 1
    194e:	de 01       	movw	r26, r28
    1950:	11 96       	adiw	r26, 0x01	; 1
    1952:	01 90       	ld	r0, Z+
    1954:	0d 92       	st	X+, r0
    1956:	8a 95       	dec	r24
    1958:	e1 f7       	brne	.-8      	; 0x1952 <_Z6TabSinh+0x22>
    195a:	29 2f       	mov	r18, r25
    195c:	96 ff       	sbrs	r25, 6
    195e:	06 c0       	rjmp	.+12     	; 0x196c <_Z6TabSinh+0x3c>
    1960:	30 e0       	ldi	r19, 0x00	; 0
    1962:	20 95       	com	r18
    1964:	30 95       	com	r19
    1966:	2f 73       	andi	r18, 0x3F	; 63
    1968:	33 27       	eor	r19, r19
    196a:	02 c0       	rjmp	.+4      	; 0x1970 <_Z6TabSinh+0x40>
    196c:	2f 73       	andi	r18, 0x3F	; 63
    196e:	30 e0       	ldi	r19, 0x00	; 0
    1970:	e1 e0       	ldi	r30, 0x01	; 1
    1972:	f0 e0       	ldi	r31, 0x00	; 0
    1974:	ec 0f       	add	r30, r28
    1976:	fd 1f       	adc	r31, r29
    1978:	e2 0f       	add	r30, r18
    197a:	f3 1f       	adc	r31, r19
    197c:	80 81       	ld	r24, Z
    197e:	97 fd       	sbrc	r25, 7
    1980:	81 95       	neg	r24
    1982:	c0 5c       	subi	r28, 0xC0	; 192
    1984:	df 4f       	sbci	r29, 0xFF	; 255
    1986:	0f b6       	in	r0, 0x3f	; 63
    1988:	f8 94       	cli
    198a:	de bf       	out	0x3e, r29	; 62
    198c:	0f be       	out	0x3f, r0	; 63
    198e:	cd bf       	out	0x3d, r28	; 61
    1990:	df 91       	pop	r29
    1992:	cf 91       	pop	r28
    1994:	08 95       	ret

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

в новых версиях иде включен оптимизатор, попробуйте поставить это

https://github.com/MCUdude/MiniCore

тут можно управлять этим

Logik
Offline
Зарегистрирован: 05.08.2014

dimax пишет:

Logik, видимо оптимизация другая. Про "ничего тяжёлого нет" -хорошая шутка :)  

Это я намекаю на отсутствие плавающей запятой, длинных целых и пр..

Logik
Offline
Зарегистрирован: 05.08.2014

dimax пишет:

 Тоесть на всё про всё у нас максимум остаётся ещё 128 тактов мк. :-\  ps: (если конечно ничего не напутал, я могу:)

Все так. Но на старых же ИДЕ работало! Это у меня неперебиваемый козырь ))))

ПС. Йооо... Шо оно накомпилило в TabSin. Рыдаю!

1958:   e1 f7           brne    .-8         ; 0x1952 <_Z6TabSinh+0x22>

Какие циклы!! )))

Скока раз?! 

1948:   80 e4           ldi r24, 0x40   ; 64

64!!! Бля!

Logik
Offline
Зарегистрирован: 05.08.2014

Попытки поменять все на uint8_t и int8_t, и прочие шевеления ниче не решили. 

Зато проблема очень четко определена - оно полюбому компилит чтение TabSin[..] через цикл!

Даже так если.

int8_t TabSin(uint8_t x)
{
const uint8_t TabSinC[64]={0, 3,  6,  9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49,
                       51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90,
                       92, 94, 96, 98,100,102,104,106,107,109,111,112,113,115,116,117,
                      118,120,121,122,122,123,124,125,125,126,126,126,127,127,127};


int8_t r=TabSinC[x];
 return r;
}

Я представляю че там в остальных проектах, где не критична скорость была. Писец, перешел на 1.8.8 ))))

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

и еще в 1.8.8 много ошибок, поставьте 1.8.9

Logik
Offline
Зарегистрирован: 05.08.2014

Спасибо, Valera19701, наверно я так и зделаю. Но позже, я уже деморализован :)

Logik
Offline
Зарегистрирован: 05.08.2014

На последок поменял опцию оптимизации -Os на -O1 и -O3 (в всех трех местах platform.txt) Безтолку. Размер растет, скорость нет.

kostyamat
Offline
Зарегистрирован: 16.11.2017

Да, ардуино уже сильно не тот.

Тут компилятор такое вытворять начал, на той же 1.8.9 -  у меня сейчас через раз выскакивает ошибка  - "не для вашей платы", при этом повторяешь компиляцию - все проходит гладко, достаточно пустую строку куда-то вставить. А скачки размера в килобайт туда сюда, добивив один if else - вообще песня. :(( Самое прикольное, когда от плюс одной команды размер уменьшается на почти килобайт. Это как так то?

Jaeger
Jaeger аватар
Offline
Зарегистрирован: 23.03.2018

Logik пишет:

На последок поменял опцию оптимизации -Os на -O1 и -O3 (в всех трех местах platform.txt) Безтолку. Размер растет, скорость нет.

Оперативно изменить уровень оптимизации можно директивой компилятора:

#pragma GCC otimize ("-Ox") //где х - 0, 1, 2, 3, fast, g, s - уровень оптимизации

можно применять как ко всей программе так и к частям программы, а так же к функциям. 

Logik
Offline
Зарегистрирован: 05.08.2014

Победил проблему на 1.8.8 и 1.8.9, теперь проект отрабатывает по виду как в 1.0.6, скорость на глаз такаяже.

Помог static. После этого дизасемблер выдал куда более приличное


inline signed char TabSin(unsigned char x) __attribute__((always_inline));
.....

inline signed char TabSin(unsigned char x)
{
static const byte TabSin[64]={0, 3,  6,  9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49,
                       51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90,
                       92, 94, 96, 98,100,102,104,106,107,109,111,112,113,115,116,117,
                      118,120,121,122,122,123,124,125,125,126,126,126,127,127,127};

signed char r=TabSin[((x&0x40)?-x-1:x)&0x3f];
 if(x&0x80)
   return -r;
 return r;
  
}

Собралось в. (Это без принудительного инлайна)

000018c2 <_Z6TabSinh>:
    18c2:	28 2f       	mov	r18, r24
    18c4:	86 ff       	sbrs	r24, 6
    18c6:	06 c0       	rjmp	.+12     	; 0x18d4 <_Z6TabSinh+0x12>
    18c8:	30 e0       	ldi	r19, 0x00	; 0
    18ca:	20 95       	com	r18
    18cc:	30 95       	com	r19
    18ce:	2f 73       	andi	r18, 0x3F	; 63
    18d0:	33 27       	eor	r19, r19
    18d2:	02 c0       	rjmp	.+4      	; 0x18d8 <_Z6TabSinh+0x16>
    18d4:	2f 73       	andi	r18, 0x3F	; 63
    18d6:	30 e0       	ldi	r19, 0x00	; 0
    18d8:	f9 01       	movw	r30, r18
    18da:	e3 54       	subi	r30, 0x43	; 67
    18dc:	fe 4f       	sbci	r31, 0xFE	; 254
    18de:	90 81       	ld	r25, Z
    18e0:	87 fd       	sbrc	r24, 7
    18e2:	02 c0       	rjmp	.+4      	; 0x18e8 <_Z6TabSinh+0x26>
    18e4:	89 2f       	mov	r24, r25
    18e6:	08 95       	ret
    18e8:	89 2f       	mov	r24, r25
    18ea:	81 95       	neg	r24
    18ec:	08 95       	ret

 Хоть тоже не блеск вобщем.

Старая версия инлайнила функцию автоматом, а здесь пришлось принудить __attribute__((always_inline)). После этого на вид дизассемблер еще приличней стал.

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:

 а здесь пришлось принудить __attribute__((always_inline)).

Видишь - есть плюсы. Что-то заставило тебя прочесть документацию по GCC. ;)))

Ты еще много интересного найдешь. Так как есть еще неочевидные приоритеты оптимизатора и атрибутов, типа "всегда инлайн" и  разворачивания циклов. А если полностью отключить оптимизатор, то код становится монстром. А вот тонко отключить только ненужную тебе фичу вообще не всегда возможно, даже если ты сообразил, как разработчики эту фичу назвали. ;)))

Вероятно, как я думаю, разработчики полагают, что дефолтно кодит 99% програмистов. Те, кому нужны реал-тайм привязки станут либо использовать платформу с запасом по железу, либо отключать весь интеллект компилятора и в критических места делать ассемблерные вставки. Как пример - исходник оптибута.

Мы же, с железом используемым на грани возможности, вынуждены балансировать, как на канате. Многие бойцы уже устали и перешли на ESP и STM, что концептуально - правильнее, по моему "хамб опиньён".

"Теплый и ламповый" AVR для меня был входом в мир МК, так как во времена PIC я занимался совсем другими вещами, но пора о нем забыть, как о кассетном магнитофоне, дискетах и наручных часах. ;))

-NMi-
Offline
Зарегистрирован: 20.08.2018

Logik пишет:

Попытки поменять все на uint8_t и int8_t, и прочие шевеления ниче не решили. 

Зато проблема очень четко определена - оно полюбому компилит чтение TabSin[..] через цикл!

Даже так если.

int8_t TabSin(uint8_t x)
{
const uint8_t TabSinC[64]={0, 3,  6,  9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49,
                       51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90,
                       92, 94, 96, 98,100,102,104,106,107,109,111,112,113,115,116,117,
                      118,120,121,122,122,123,124,125,125,126,126,126,127,127,127};


int8_t r=TabSinC[x];
 return r;
}

Я представляю че там в остальных проектах, где не критична скорость была. Писец, перешел на 1.8.8 ))))

Иче тебе мешало написать енто всё на ассемблере?

Сохраним регисры ~~ 20 тактов

Загружаем в Х указатель на адрес таблицы - 2 такта

Загружаем в Z смещение по таблице 2 такта

Прибавляем X к Z 2 такта

Забираем по Z  и сохраняем где хотим - 4 такта

Восстанавливаем регистры и выходим...

Ну... 100 тактов максимум.

Logik
Offline
Зарегистрирован: 05.08.2014

Я чето в этом

    18de:	90 81       	ld	r25, Z
    18e0:	87 fd       	sbrc	r24, 7
    18e2:	02 c0       	rjmp	.+4      	; 0x18e8 &lt;_Z6TabSinh+0x26&gt;
    18e4:	89 2f       	mov	r24, r25
    18e6:	08 95       	ret
    18e8:	89 2f       	mov	r24, r25
    18ea:	81 95       	neg	r24
    18ec:	08 95       	ret

не вижу ни приоритета по размеру (а это с опцией Os) ни интелекта компилятора.

Не стоит придумывать сложных построений для оправдания распиздяйства и халтуры. Этот метод не нов. Любого карманника сцапают - он раскажет что все воруют, а при власть сильней всех. Но эта демагогия ниче не меняет. Переписать все на асм - конечно вариант, нахер те плюсы ;) Я уже и начал было, но подумал дай статик попробую ))) 

//но пора о нем забыть

не думаю. Каждой цели свой калибр. У меня железа разного хватает, и АВР там самое нижнее звено на пару с ESP8266 (нужна сеть ESP, нет - знач АВР), его не реально исключить. STM попробовал - херня. Это без меня. Нужно "потяжелей" АВР - сразу линуксовое беру, благо от 10 баксов нынче.

Logik
Offline
Зарегистрирован: 05.08.2014

-NMi- пишет:

Иче тебе мешало написать енто всё на ассемблере?

Мешало важнейшее преимущество плюсов. Кросплатформенность. Да и время написания явно сократилось. 

Грабли из за кривой компиляции к сожалению в обоих случаях могут заставить такой херней заниматся как мне тут пришлось.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:
Не стоит придумывать сложных построений для оправдания распиздяйства и халтуры.

Ты чо сразу в защиту встал? ;))) Я как раз про то сказал - в компиляторе много странностей. Я его знаю, возможно, лучше тебя, и всё равно постоянно нарываюсь на непредсказуемое поведение. Так что я тут за тебя, просто "затебее всех" ;).

Я писал про свой опыт, а не касаемо твоей задачи. У меня как раз оптимизатор циклы разворачивал, по неведомому мне закону, не всегда реагируя на многочисленные атрибуты. ;)

Я б не стал говорить вот-прям-резко: "распиздяйство и халтура", про самый распространенный компилятор, но дыр и багов в нем хватает. Но для AVR ты все равно не найдешь другого ;)))))))).

Logik
Offline
Зарегистрирован: 05.08.2014

Так не вопрос и что gcc  самый распространенный, и что другого не найдеш - согласен. Меж мне, каждое сообщение с этого начинать?! )))) И что дыр и странностей много - тоже правда. И тоже никто не спорит! ;)

Вопрос в другом. С выходом новых версий дыр и странностей становится все больше. Причем появляются там, где ранше не было. А это уже тяжело назвать  иначе чем  распиздяйством и халтурой. А из-за такого и звания самый-самый очень легко лишится, примеров тому - да вся история IT тому сплошные примеры. Мне бы этого не хотелось чтоб gcc сдох как глюкавый и непредсказуемый инструмент. И не хочется и перелопачивать старые проекты. Потому и называю вещи своими именами.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Логик! Я немного позанудствую, потому, как Женя игнорит такие терки ... и, в целом, это правильно! ;))

Попробуй не вставать в защиту, а выслушать вариант, по которому новая версия компилятора делает всё правильно.

В старом коде у тебя не было "статик". В понимании стандарта  Си, без всяких оптимизаций, ты размещаешь массив на стеке. Зачем? - не дело компилятора. Оптимизатор видит, что факт размещения на стеке никак не используется, но массив - не СТАТИК, значит нужно его в коде скопировать куда-то - а потом забыть. Нельзя его использовать, как СТАТИК, програмист так решил.

Прошлая версия автоматом за тебя решала перекроить в СТАТИК, и там был возможен баг, где ты в функции изменишь массив, но никто об этом не узнает. И в следующий заход в функцию данные будут другие. Можно изменить так, что на этапе компиляции это не будет отловлено, даже если ты КОНСТ написал.

Так что нововведения - они не просто так. Тебе они проявили баг автора (все-таки таблица не СТАТИК, это явный  баг автора кода), а у кого-то наоборот - баг исправили.

Не "сдуру" вносятся в алгоритм оптимизатора такие правки. В этой версии оптимизатор точнее следует указаниям програмиста. и твой пример - как раз об этом. Не его (оптимизатора) дело решать, забыл ты про СТАТИК, или специально сделал так, что массив может претерпеть изменения.

========================

Отдельно, про твой старый код: я понимаю, что он работал в старой версии компилятора. Но в понимании классики, динамическая переменная, тем более массив на 64 байта, должна съедать время на входе в функцию, и съедать время, освобождая память на выходе. То что оптимизатор это убрал - здорово, но лучше, чтобы он за меня ТАКИЕ решения не принимал. И скопировать 64 байта, а потом освободить память - реально ПРАВИЛЬНОЕ решение, даже если тебе кажется иначе.

Только прежде чем ругаться на меня и компилятор, подумай немножко, может я прав? ;))

Green
Offline
Зарегистрирован: 01.10.2015

А вообще то грустно. Ну на кой мне знать как работает комплилятор! Его фишки, его особенности. По большому счёту.

Logik
Offline
Зарегистрирован: 05.08.2014

))) wdrakula, те явно "а поговорить!" захотелось ;) Ну какое размещение на стеке может быть, если явно указано что константа! Но даже если взять на секунду допустить что компилятор в праве взять константу и разместить в сегменте стека чтоб её там каждый раз инитит, так нахрена он это делает? Это оптимизация по скорости или размеру? ;) Это разве что назло разрабу сделать длинней и медленей. Но я не думаю что там так коварны, скорей слегка туповаты.

Logik
Offline
Зарегистрирован: 05.08.2014

Green пишет:

А вообще то грустно. Ну на кой мне знать как работает комплилятор! Его фишки, его особенности. По большому счёту.

Да. Согласен, знать особенности и "задвиги" совершенно не продуктивное занятие, особенно когда их (и задвигов и компиляторов) много. Да в каждой версии - новый!  Но виш, есть товарищи, считающие что если очередная версия компилятора заставляет рытся в его доке - харашеее! Каких тока паталогий не встретиш в инете ;)

Хороше хоть проекту ардуиновского - пол сотни КБ, еще реально найти и поправить. А если  бы по работе такое. Не дай господи!

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Вот ведь вопрос, что лучше:

- исправление ошибок, к которым уже [почти] все привыкли,

- сохранение ошибок ради совместимости снизу вверх.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Это конечно вопрос философский. И холиварный. Но думаю конкретно в данном случае не в этом дело. Просто GCC внедряет новые спецификации с++14 и т.д. Но на платформе AVR есть своя специфика и именно с константами. Вот при попытке перенести доработки новых спецификаций с х86 на AVR и вылазят различия архитектур. И это старые грабли, помнится указатели на не виртуальные методы класса тоже когдато в ОЗУ копировали. Кстати в моем примере константы аж в 3-х местах память отжирают: в флеше, в ОЗУ как обычно с константами было и еще раз в ОЗУ на стеке ))) Прям с жиру бесятся ))) 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Логик!

Во первых, я могу ошибаться, но изначально у тебя даже КОНСТ не было, так? ;)

Во вотрых - ты же сделал, в итоге, правильно: написал СТАТИК КОНСТ. ;) чем повысил свой скилл ;)))) 

И утилитарная и педагогическая функции компилятора - обе выполнены. Профит, не?

И третье: мы ж и правда внутри очень маленького 8ми битного контроллера. Зачем тащить сюда приемы "большого" кодинга? Зачем константный массив внутри функции. Тут все-равно Гарвардская архитектура, данные все равно лежат отдельно - ну и делай его глобалом... ну чисто ИМХО. Посмотри на "фирменные" вещи, типа адафутовских библиотек экранов. Там шрифты разве локально лежат?

Logik
Offline
Зарегистрирован: 05.08.2014

wdrakula пишет:

Логик!

Во первых, я могу ошибаться, но изначально у тебя даже КОНСТ не было, так? ;)

Нет, конечно, там конст изначально.

 

wdrakula пишет:

Во вотрых - ты же сделал, в итоге, правильно: написал СТАТИК КОНСТ. ;) чем повысил свой скилл ;)))) 

Та не выдумуй! Скилл на таком не повышают. Даже студенты.  У меня сейчас актуальное - запаковать векторный шрифт, 160 символов с кирилицей в 800 байт. А для этого нада придумать алгоритм анализирующий начертание каждого символа на предмет общих элементов, вынести эти общие элементы и компактно хранит. Потом рекурсивно повторить процесс. А затем учесть различные возможные варианты решений и выбрать оптимальный. Ну и учесть возможные варианты порядка начертания частей символа. Это слава богу в студии делается ;) Я те расписал подробно чтоб ты понимал насколько мне "интересно" и "полезно" столкнутся с сраным статиком при переноске проекта в новую ИДЕ устанавливая по причине того что новый комп обживать нужно. Прогер растет на алгоритмах, а не на поиске куда статик впиндюрить чтоб компилятор стал вменяемым. 

wdrakula пишет:

И утилитарная и педагогическая функции компилятора - обе выполнены. Профит, не?

Нет. Не профит. Я потерял время на херню. У меня закрадываются смутные сомнения, а ты сам то не из этих пи... , ну пидагогов? Рассуждаеш как прохвесор какой вшивый ;) Ну представь ты вышел из дому глубоко задумавшись о проблемах компилятора, а тротуар перекопали и пришлось изучать пути обхода траншеи по соседним свалкам, сел в автобус - а те гвоздь в жопу, потому как вчера в правила пасажира добавили пункт что пасажир сам должен убедится в отсутствии гвоздя и навсяк случай подложить сковородку и т.д. Профит от изучения месности, правил и гвоздя? Не хочу дальше упражнятся в  демагогии, тебе демагогить в кайф, я смотрю, а мне шото неохота. Хочеш колебатся с линией парт.. компилятора ;) и гордится этим - ну успехов. У меня другие предметы для гордости ;)

wdrakula пишет:

И третье: мы ж и правда внутри очень маленького 8ми битного контроллера. Зачем тащить сюда приемы "большого" кодинга? Зачем константный массив внутри функции. Тут все-равно Гарвардская архитектура, данные все равно лежат отдельно - ну и делай его глобалом... ну чисто ИМХО. Посмотри на "фирменные" вещи, типа адафутовских библиотек экранов. Там шрифты разве локально лежат?

Инкапсуляция называется. Зачем нужна - ну долго рассказывать, загугль;) В шрифтах своя специфика, там кодогенератор вобще располагают в отдельный файл для простоты замены. И я так тоже делаю. Но https://www.youtube.com/watch?v=EWXriSE6KbY. Т.е. аналогия между килобайтным знакогенератором и функцией прерывания несколько натянута.

Ты мне так и не ответи про оптимизатор. Вот это его решение, копировать 64 байта из одной области ОЗУ в другую каждый раз при вызове. Оно очевидно из ряда возможных выбрано, так оно оптимизация по скорости или по размеру?  старая версия выбирала другй вариант к ней вопроса нет, а про "там был возможен баг, где ты в функции изменишь массив, но никто об этом не узнает." - чесать не надо! Плохо что ты не разбираешся в вопросе, а берешся расказывать. В AVR все что в ОЗУ никак не защищено от стрельбы по памяти. Потом это копирование из ОЗУ в ОЗУ ни как не поможет (вот если бы из PROGMEM копирывали - это было бы шото!).  Могу примером проилюстрировать если буш возражать, я просто "бахну" в ОЗУ туда, откуда копируется ;) А вот от изменения константы штатным присвоением, как раз константность защищает, но только на стадии компиляции, увы одинаково во всех возможных. 

ПС. Отдельное спасибо всем посоветовавшим добавить статик ;) "Был бы я такой умный вчеракак моя жена сегодня"

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Логик, прости, но из тебя "архатовщина" поперла мутным потоком. Уже и я "не разбираюсь в вопросе" и неправ не ты, а авторы компилятора... пусть. Я полностью согласен со всеми доводами. И я - дурак и компилятор говно. Лишь бы был мир благость и процветание.

Logik
Offline
Зарегистрирован: 05.08.2014

ОК. На том и завершаем, коль ты в бутылку полез, мои вопросы не замечаеш и обижаешся на замечания по отсутствию компетенции. Зря. Всего знать нельзя.   Мы же по существу говорили. Заметь я даже не стал сразу на ту пургу в #21 реагировать, новичек сюда точно не полезет, а кто разбирается  - сам поймет про константы на стеке.   Но ты на будущее подразберись в вопросе возможностей защиты ОЗУ от изменения, коль уж о нем хочеш говорить. Может всеж примерчик нужен или уже понял?

Я свои вопросы решил в части этой темы, свой опыт изложил, глядиш кому поможет. Тему можна и закрывать.  

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Про шрифты. Ты  "поразить наповал" решил? ;))

Не стану троллить, но ты ведь слышал о векторных шрифтах? pfa,pfb,ttf и все эти вещи?

Я обещал не троллить - поэтому понимаю, что слышал. Общий принцип понимаешь?

Если ты хочешь по любому фирменному шрифту собрать свой векторный код - то тут боюсь и правда засада выйдет. Можно, но глупо. И шрифты  с засечками просто не влезут в 800 байт, как ни жми.

Если нарисовать свой в 800 байт - говно вопрос.

Берешь только три типовых глифа: moveto, lineto, quadto. Из них собираешь шрифт, написав предварительно редактор на любимом языке. Я бы выбрал Python, ты - C#, вероятно. Параметры глифов (x,y) - относительные, по три бита, два бита - код глифа(можно 4-ый придумать...). Выйдет 1 байт на M и L и 2 байта на Q. Какие-то символы выйдут длиннее 5 байт, какие-то короче.

Logik
Offline
Зарегистрирован: 05.08.2014

wdrakula пишет:

Если нарисовать свой в 800 байт - говно вопрос...

Увереность дилетантов - предмет зависти профи ;)

Почитай http://arduino.ru/forum/programmirovanie/krivye-beze?page=1 отсюда растет, с картинками и мультиками.

5 байт  говориш? ))) Вот глифы для "8" в 9х17.

len=17 [ 0xa8, 0x07, 0x09, 0x0c, 0x34, 0x0b, 0x0e, 0x0d, 0x02, 0xb1, 0x6a, 0x43, 0x35, 0x1d, 0x21, 0x4e, 0x81,]

Ну может так понятней, а то там уже паковано слеганца.

/* 8 */  17 * 2, M_CMD(0, 2), L_CMD(2, 0), L_CMD(6, 0), L_CMD(8, 2), L_CMD(8, 5), L_CMD(6, 7), L_CMD(2, 7), L_CMD(0, 5), L_CMD(0, 2), M_CMD(6, 7), L_CMD(8, 9), L_CMD(8, 13), L_CMD(6, 15), L_CMD(2, 15), L_CMD(0, 13), L_CMD(0, 9), L_CMD(2, 7),
 

//два бита - код глифа(можно 4-ый придумать...). )))

Аж 4!!! А не слишгом ли многа для кодовой таблицы на 160 символов ;)

Её богу, wdrakula, просто прелестен! https://www.youtube.com/watch?v=dc82k-StawA 

Просто сделал мой день! )))

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:

Просто сделал мой день! )))

Упрямый дурак, хуже просто дурака... Точно Архат, который нес пургу, а все остальные были дилетанты.

Внимательно: по этой теме - у тебя был говнокод, который прокатывал на старой версии.

По шрифтам. ДОСТАТОЧНО не 5 бит, а три на координату в относительных кодах и ТРИ "команды", как ты глифы называешь: M, L ,  Q - где Q - Безье квадрика в точку с одной опорной. И шрифт рисовать под такой код.

"8" состоит из двух линий (центрального крестика) и двух дуг - сверху и снизу, 17 байт - это ты сам нарисовал? Мамка похвалила? Художнег!!! "Не дилетант", ипона срака! Еще и в дискуссию лезет, дебил.

---------------------

Психически здоровый человек возьмет ESP c 4 Мегами и нативной поддержкой Трутайпа. И вообще не станет решать ничемную задачу.

Logik
Offline
Зарегистрирован: 05.08.2014

wdrakula пишет:

"8" состоит из двух линий (центрального крестика) и двух дуг - сверху и снизу

Задумчиво смотрю на эту "8", ну да, кому и кобыла невеста, кому и крестик сойдет. Но вощето "8" даже из твоего сообщения както не так выглядит. А шрифты у тя на компе какие? ;)

А вот про дуги - это ты верно заметил, они автоматом идут в библиотеку. И везде где встречаются - там на них ссылка. Например втречаются в кружке "6". Но проблема в том что и этот кружек очень распостранен, его тоже в библиотеку. Таким образом каждый символ раскладывается на М,  L (ну ты уже понял это) и ссылки  на библиотечные элементы. Рекурентные разумеется, с уровнем рекурсии гдето до 5.  И вотето должно само генерится и оптимизироватся по размеру.  Заметь что каждый символ еще и можна начинать рисовать с нескольких мест "6" - с 2-х если по здравому (но нельзя исключать что они окажутся не наилучшими при глобальной оптимизации :((( ) а "8" - воще ХЗ откуда и сколькими способами.  И это бы тоже автоматом хорошо бы закодить ;) Вот на таком скилл растет, а не на статик дописать. Наверно просто они у нас сильно разные ;) Но ты не нервничай, таких как я не много;) , ну просто те неповезло малость ;)

wdrakula пишет:

Психически здоровый человек возьмет ESP c 4 Мегами и нативной поддержкой Трутайпа. И вообще не станет решать ничемную задачу.

Ээээ... А как же...

wdrakula пишет:

Если нарисовать свой в 800 байт - говно вопрос.

Определись)))