Светодиодные фонари и световые приборы. Всё о светотехнике.
Изображения Дневники Группы Поиск
Вернуться   Форум FONAREVKA.RU Лаборатория Электроника и схемотехника Электроника Микроконтроллеры
Расширенный поиск
Забыли пароль? Регистрация

  • О нашем проекте
  • Светотехника и световые приборы
  • Правила форума
Проект FONAREVKA.RU специализируется на предоставлении всей необходимой информации по светотехнике:

— светодиодные фонари;
— различные источники питания;
— разнообразные зарядные устройства;
— освещение помещений и наружное освещение;
— световые приборы для личного, пассажирского и грузового транспорта;
— специальные световые приборы для медицины, для растений, для аквариумов, для террариумов, а также аварийно-сигнальные световые приборы;
— альтернативные источники света;
— лазеры и лазерная техника.

Если у вас есть вопросы по выбору фонарей, аккумуляторов и зарядных устройств ознакомьтесь с FAQ от наших экспертов:

F.A.Q. по выбору фонарей различных типов;
F.A.Q. по выбору аккумуляторов;
F.A.Q. по выбору зарядных устройств.
Ответ  Создать новую тему
Просмотров в теме 10826   Ответов в теме 28   Подписчиков на тему 0   Добавили в закладки 0
Опции темы Поиск в этой теме
Старый 16.09.2010, 21:22   21
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

Отправить сообщение для SviMik с помощью ICQ Отправить сообщение для SviMik с помощью MSN
По умолчанию

Цитата:
Посмотреть сообщение Сообщение от yuri :
У меня глаз к ассемблеру не слишком привычен, но на мой взгляд, это более чем приличный код для 64-хбитного суммирования. Занимает 256 байт. А как бы это написал опытный ассемблерщик? Неужели эту функцию можно впихнуть в 25 байт? Или даже в 100 байт?
Результат вычислений красным слева. Как говорится, Epic Fail, господа
"няшная сишечка", как же
Вложение 1562
48 байт. Из них непосредственно вычисления - 16 байт, и 32 байта - чтобы забить числа в озу.
Миниатюры
Нажмите на изображение для увеличения
Название: asmadd.png
Просмотров: 712
Размер:	16.7 Кб
ID:	253099
SviMik вне форума   Ответить с цитированием Вверх
Старый 16.09.2010, 21:23   22
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 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"
);
}

А попробуйте эту функцию написать на чистом Си, и скомпилируйте. Я не говорю про умножение и деление там будет еще веселее.
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 16.09.2010, 21:36   23
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 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 минуты
Цитата:
Посмотреть сообщение Сообщение от SviMik :
48 байт. Из них непосредственно вычисления - 16 байт, и 32 байта - чтобы забить числа в озу.
Так я про то и грю, что на Асме можно те-же регистры использовать и для дальнейших вычислений, и убрать лишние пересылки.
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 16.09.2010, 21:51   24
lasers_yuri
Увлеченный
 
Аватар для lasers_yuri
 
Регистрация: 12.02.2010
Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

2 SviMik, AVSel

Да, убедительно.
__________________
lasers_yuri вне форума   Ответить с цитированием Вверх
Старый 16.09.2010, 22:09 Автор темы   25
lasers_INFERION
Ветеран Фонарёвки
 
Аватар для lasers_INFERION
 
Регистрация: 15.02.2010
Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

yuri. Как я понимаю, твой компилятор не знал команды ADC (сложить с учётом переноса), поэтому код получился громоздкий. Думаю некорректно это приводить как пример. А-то результат слишком пугающий...

Я всё вспоминаю человека, который пытался написать линейный индикатор заряда на 5-ти светодиодах, на паскале. По-сути просто загораются светики на своих порогах зажигания. Так у него в память (1кБ) не влез последний светик. На ассемблере в килобайт столько всего влазит...
lasers_INFERION вне форума   Ответить с цитированием Вверх
Старый 16.09.2010, 23:01   26
lasers_yuri
Увлеченный
 
Аватар для lasers_yuri
 
Регистрация: 12.02.2010
Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Компилятор прекрасно знает про инструкцию adc, только что проверил некоторые другие проекты - так и складывает, сначала add, потом adc. Для того, чтобы складывать так, как он складывает, у него, наверное, есть какие-то очень веские причины.

Но да, я бы не хотел, чтобы такая штука появлялась, скажем, в цикле, который выполняется 100000000 раз, так что буду потихоньку дополнять проги ассемблерными вставками.
lasers_yuri вне форума   Ответить с цитированием Вверх
Старый 17.09.2010, 11:14   27
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 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 - экономичнее уже через указатели.
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 17.09.2010, 14:17   28
lasers_yuri
Увлеченный
 
Аватар для lasers_yuri
 
Регистрация: 12.02.2010
Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Сишечка частично реабилитировалась.

Уменьшил размер интеджера с 8 до 4 байт и получил то, что и следовало - add, adc, adc, adc, плюс оптимизацию инциализации и сложения (инициализирующие значения пишутся в регистры и сразу же там и складываются). Так что оптимизирует компилятор нормально, это, наверное, специфичный 8-мибайтовый баг (точнее, плохая оптимизация действий с типом long long, которым редко пользуются).

Ня!
lasers_yuri вне форума   Ответить с цитированием Вверх
Старый 12.10.2010, 20:09   29
Gall
Увлеченный
 
Аватар для Gall
 
Регистрация: 21.06.2010
Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Цитата:
Посмотреть сообщение Сообщение от INFERION :
yuri. Как я понимаю, твой компилятор не знал команды ADC (сложить с учётом переноса), поэтому код получился громоздкий. Думаю некорректно это приводить как пример. А-то результат слишком пугающий...

Я всё вспоминаю человека, который пытался написать линейный индикатор заряда на 5-ти светодиодах, на паскале. По-сути просто загораются светики на своих порогах зажигания. Так у него в память (1кБ) не влез последний светик. На ассемблере в килобайт столько всего влазит...
Обычно причина несколько в другом. На Си можно по неопытности написать просто немного не тот код, который хотелось бы. Например:
Код:
int x;
unsigned y;
...
if (x + 1 > y) { ... }
Казалось бы, тут все просто: add, cmp... На самом деле - нет. Дело в том, что x - число знаковое, а y - беззнаковое, и поэтому надо учитывать возможность знакового переполнения. Компилятор это прекрасно понимает и вставит в код соответствующие "лишние" инструкции. А вот программист, скорее всего, написал такой код по неряшливости, не задумываясь о последствиях. Поэтому программист на Си должен всегда следовать двум заповедям:
1. Пиши строго то, что думаешь, а не то, как можно "просто написать". Например, если тебе нужна переменная для пробегания по циклу от 0 до 100, то она должна быть беззнаковой - unsigned, а не int. А если тебе нужен байт, то это uint8_t, а вовсе не char. А вот буква - наоборот, char. Ну и так далее. Если писать так, то компилятору будет гораздо легче понять, что ты имел в виду, и код получится гораздо оптимальнее.
2. Всегда включай в компиляторе самый жестокий режим поиска ошибок - -Wall -Wextra --pedantic -Werror для gcc, например. Тогда неряшливого написания компилятор не простит.
Gall вне форума   Ответить с цитированием Вверх
Ответ  Создать новую тему





Copyright ©2007 - 2024, FONAREVKA.RU

Powered by vBulletin®
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd. Перевод: zCarot

Правила форума | Отказ от ответственности

Время генерации страницы 0.11200 секунды с 19 запросами