|
|
|
|
10867 28 0 0 |
|
Опции темы | Поиск в этой теме |
16.09.2010, 21:22 | 21 | |
Завсегдатай Фонарёвки
|
Цитата:
"няшная сишечка", как же Вложение 1562 48 байт. Из них непосредственно вычисления - 16 байт, и 32 байта - чтобы забить числа в озу. |
|
16.09.2010, 21:23 | 22 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Наверное я не так выразился. Этот компилятор уже умеет работать с int64, и этот код писал разработчик на Асм-е.
А большинство не умеет, или не умело в более ранних версиях, только long. И мне приходилось писать свои функции. Вот примерчик. typedef union { unsigned long l[2]; unsigned char c[8]; } Int64; void Int64ADD(Int64 *d,Int64 *s) { asm( "mov r30,r16\n" "mov r31,r17\n" "mov r26,r18\n" "mov r27,r19\n" "ld r0,Z\n" "ld r1,X+\n" "add r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" "ld r0,Z\n" "ld r1,X+\n" "adc r0,r1\n" "st Z+,r0\n" ); } А попробуйте эту функцию написать на чистом Си, и скомпилируйте. Я не говорю про умножение и деление там будет еще веселее. |
16.09.2010, 21:36 | 23 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
кстати вот листинг
007E ; void Int64ADD(Int64 *d,Int64 *s) 007E ; { 007E .dbline 90 007E ; asm( 007E E02F mov r30,r16 0080 F12F mov r31,r17 0082 A22F mov r26,r18 0084 B32F mov r27,r19 0086 0080 ld r0,Z 0088 1D90 ld r1,X+ 008A 010C add r0,r1 008C 0192 st Z+,r0 008E 0080 ld r0,Z 0090 1D90 ld r1,X+ 0092 011C adc r0,r1 0094 0192 st Z+,r0 0096 0080 ld r0,Z 0098 1D90 ld r1,X+ 009A 011C adc r0,r1 009C 0192 st Z+,r0 009E 0080 ld r0,Z 00A0 1D90 ld r1,X+ 00A2 011C adc r0,r1 00A4 0192 st Z+,r0 00A6 0080 ld r0,Z 00A8 1D90 ld r1,X+ 00AA 011C adc r0,r1 00AC 0192 st Z+,r0 00AE 0080 ld r0,Z 00B0 1D90 ld r1,X+ 00B2 011C adc r0,r1 00B4 0192 st Z+,r0 00B6 0080 ld r0,Z 00B8 1D90 ld r1,X+ 00BA 011C adc r0,r1 00BC 0192 st Z+,r0 00BE 0080 ld r0,Z 00C0 1D90 ld r1,X+ 00C2 011C adc r0,r1 00C4 0192 st Z+,r0 00C6 00C6 .dbline -2 00C6 L6: 00C6 .dbline 0 ; func end 00C6 2496 adiw R28,4 00C8 0895 ret Занимает 74 байта, можно еще короче, если под параметры Сишного вызова функции не подгонятся. Добавлено через 3 минуты Так я про то и грю, что на Асме можно те-же регистры использовать и для дальнейших вычислений, и убрать лишние пересылки. |
16.09.2010, 21:51 | 24 |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
|
16.09.2010, 22:09 | 25 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
yuri. Как я понимаю, твой компилятор не знал команды ADC (сложить с учётом переноса), поэтому код получился громоздкий. Думаю некорректно это приводить как пример. А-то результат слишком пугающий...
Я всё вспоминаю человека, который пытался написать линейный индикатор заряда на 5-ти светодиодах, на паскале. По-сути просто загораются светики на своих порогах зажигания. Так у него в память (1кБ) не влез последний светик. На ассемблере в килобайт столько всего влазит... |
16.09.2010, 23:01 | 26 |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Компилятор прекрасно знает про инструкцию adc, только что проверил некоторые другие проекты - так и складывает, сначала add, потом adc. Для того, чтобы складывать так, как он складывает, у него, наверное, есть какие-то очень веские причины.
Но да, я бы не хотел, чтобы такая штука появлялась, скажем, в цикле, который выполняется 100000000 раз, так что буду потихоньку дополнять проги ассемблерными вставками. |
17.09.2010, 11:14 | 27 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
На самом деле не все так плохо с Си, оптимизировать можно и сам Сишный код, ручная оптимизация ничуть не хуже машинной, ежели с умом делать
Пример1: код для конструции вида if(){} else if(){} else if() ... получается гораздо компактнее чем аналогичный switch () { case: } По крайней на моем ICCAVR. Поэтому в прерываниях и быстрых циклах я switch() не использую. Пример 2: В ICCAVR параметры в функцию передаются через регистры R16..R19, а что не влезает, через стек. По этому 2 параметра типа char экономичнее передавать в функцию "по значению"(два регистра свободных останется), а 2 параметра типа long - экономичнее уже через указатели. |
17.09.2010, 14:17 | 28 |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Сишечка частично реабилитировалась.
Уменьшил размер интеджера с 8 до 4 байт и получил то, что и следовало - add, adc, adc, adc, плюс оптимизацию инциализации и сложения (инициализирующие значения пишутся в регистры и сразу же там и складываются). Так что оптимизирует компилятор нормально, это, наверное, специфичный 8-мибайтовый баг (точнее, плохая оптимизация действий с типом long long, которым редко пользуются). Ня! |
12.10.2010, 20:09 | 29 |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
Код:
int x; unsigned y; ... if (x + 1 > y) { ... } 1. Пиши строго то, что думаешь, а не то, как можно "просто написать". Например, если тебе нужна переменная для пробегания по циклу от 0 до 100, то она должна быть беззнаковой - unsigned, а не int. А если тебе нужен байт, то это uint8_t, а вовсе не char. А вот буква - наоборот, char. Ну и так далее. Если писать так, то компилятору будет гораздо легче понять, что ты имел в виду, и код получится гораздо оптимальнее. 2. Всегда включай в компиляторе самый жестокий режим поиска ошибок - -Wall -Wextra --pedantic -Werror для gcc, например. Тогда неряшливого написания компилятор не простит. |