реклама на сайте
подробности

 
 
5 страниц V  « < 2 3 4 5 >  
Reply to this topicStart new topic
> Сопоставление проектов С и АСМ, Немного цифр
defunct
сообщение Feb 23 2008, 00:10
Сообщение #46


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ Feb 23 2008, 01:55) *
Вот здесь хотелось бы разъяснений и поподробнее...(без подколок...),
я не понимаю как уменьшить количество глобальных переменных.

А что Вы храните в глобальных переменных?
Ведь кроме конфигурации там больше нечего хранить.
Под все остальное память можно выделить либо в стеке, либо в куче.

Цитата
Я не понимаю как можно использовать heap для уменьшения расхода памяти вместо
использования глобальных переменных...

это смотря под что у вас используются глобальные переменные.
Допустим имеем дело с неким протоколом где команды(пакеты) могут поступать не дожидаясь ответа на предыдущую команду(пакет). Предположим что глобально выделенно два буфера фиксированного размера (один обрабатывается, во второй принимается сл. команда). Попробуем сократить объем памяти.
Выделяем буфер из heap, ведем в него прием. По окончании приема, передаем указатель на этот буфер в функцию обработки, выделяем еще один буфер под прием сл. пакета и ведем прием дальше.
В функции обработки - перевыделяем память в соответсвии с реальным размером пакета (не всегда же пакет будет максимально возможной длины), или копируем во временный буфер в стеке, память освобождаем. Итого на лицо экономия памяти на 1 буфер в 99% времени работы нашего устройства (т.к. полных два буфера будет использоваться в очень короткий промежуток времени - только в момент между окончанием приема текущего пакета и запуском функции обработки).

Еще пример:
допустим по i2c раз в секунду надо что-то записать/прочитать.
Выделили буфер из heap - сказали i2c драйверу - читать/писать данные в него.
Все остальное время - эта память будет использоваться под что-то другое.

и так многие места где используются значительные объемы памяти можно разделять во времени с помощью heap'a - пользовать память эффективно (одну и ту же область для разных целей в разное время).
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 23 2008, 00:43
Сообщение #47


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Feb 23 2008, 03:10) *
А что Вы храните в глобальных переменных?
Ведь кроме конфигурации там больше нечего хранить.
Как это нечего ?
Вот вполне реальный пример, нужно по 4 каналам АЦП делать скользящее среднее по 8 измерениям,
ИТОГО:
4 * 8 * 2(байта на измерение) = 64 байта
+ 4(канала) * 2(байта) = 8 байт для хранения суммы
+ 1 байт на хранение номера канала
+ пару байт на всякие сервисные штучки
ИТОГО: ~75 байт глобальных переменных..

Пример N2:
Есть ~250байт которые есть суть текущее состояние системы, эти параметры могут быть запрошены
в любой момент например по протоколу модбас,
допустим что модбас работает на скорости 345600, можем ли мы хранить где-нить кроме глобальных
переменных эти данные ?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 23 2008, 00:58
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А мне просто супер нравится С. По-моему, для МК это совершенно оптимальный уровень абстракции. Здесь чётко видишь что такое объект или структура, что будет делать компилятор. Если необходимо вставить ASM кусок - пожалуйста, сразу видно как к сишным переменным обращаться. С другой стороны - совершенно наплевать как он память распределяет, - пусть сам думает. Как раз с этим не хочется возиться.

Я тоже наигрался с Си пытаясь добиться от него оптимального (как сделал бы сам на асме) кода. Ну кое где проколы есть у него, но он зато выигрывает при большом количестве глобальных переменных. Я не смог тут его сделать.

Не знаю как у вас получается "в два раза" - у меня 10-20%.

Единственное где можно капитально "надрать" компилятор, это если большое количество основных переменных в регистры влезает. Но это ведёт к сложности модификации программы. Что мы и имеем.

С другой стороны - какая песня иметь легко модифицируемый чёткий и ясный проект!!! Вот вы применяете кастрированную ОС своего исполнения. А если применить нормальную. Со всеми наворотами? Ну хорошо "не влазит задача". А можно спросить - куда она не влазит? Если, к примеру в m8, то есть m168/328. Разница - копейки. Если речь идёт о какой-нибудь m640, то ещё меньше разница на m1280/2560. Или на соответствующий ARM перейти со старшей модели тоже не фокус из под С. Короче, безусловно, дело вкуса, но очень спорный момент.

Когда просматриваешь кусочек, то да - кода много. А если сделать полный проект, то ваш выигрыш будет копеечный, а в замен сложная модифицируемость проекта. Си-шный сопровождать - на порядок легче. Это, конечно, моё личное мнение.
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 23 2008, 01:10
Сообщение #49


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ Feb 23 2008, 02:43) *
Как это нечего ?
Вот вполне реальный пример, нужно по 4 каналам АЦП делать скользящее среднее по 8 измерениям,
ИТОГО:
4 * 8 * 2(байта на измерение) = 64 байта

Я конечно не знаю вашей задачи полностью и возможно у вас есть некие строгие требования к сохранению фазы сигнала поэтому нужен КИХ, а я не брезгую БИХ'ом - ибо эффективней с т.з. памяти..
У меня скользящее по восьми измерениям занимает 2* U16 данных и кот наплакал кода.
итого 4 канала - 16 байт:
код для усреднения по 8-ми точкам:

Код
pChan->vAverage = (pChan->vSum + 4) >> 3;
pChan->vSum += val - pChan->vAverage;

но я не меняя размер данных могу и по 16-ти точкам усреднять и по 32-м и по 1024.
меняться будет только формула..
Конечно, это не тот случай когда heap чем-то помог, но все же думать об экономии там где это возможно - стоит.

Цитата
Пример N2:
Есть ~250байт которые есть суть текущее состояние системы, эти параметры могут быть запрошены
в любой момент например по протоколу модбас,
допустим что модбас работает на скорости 345600, можем ли мы хранить где-нить кроме глобальных
переменных эти данные ?

Статистика / параметры системы - это есть конфигурация...
Стало быть легально делать их глобальными.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 23 2008, 11:09
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Из приведенного мной первого поста видно, что проигрыш по памяти - почти двукратный.
Правда ....
1) я не оптимизировал ...
2) На оба стэка выделил значительно больше памяти, чтобы не искать потом мучительно ....
3) На асме стек не учитывал ...

Тем не менее, если это всё поучитывать + взять равноценные проекты = всё равно коэффициент 1.3~1.4 думаю найболее реальный. Но памяти сейчас в микроконтроллерах вполне достаточно. Как правило, на большинстве задач на асме она остаётся, а на Си её просто достаточно. В тех же задачах где требуется много памяти, - не спасает использование ASMа, надо вешать внешнюю.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 23 2008, 20:18
Сообщение #51


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
pChan->vAverage = (pChan->vSum + 4) >> 3;pChan->vSum += val - pChan->vAverage;


Скажем так, это все таки обычный Low Pass Filter первого порядка. Немного от скользящего среднего отличается. Правда, обычно это пофиг. Мне другой вопрос не ясен. Нафига 2 переменных в структуре? Ведь Y=Y*(1-k)-k*v <=> Y=Y-k*(Y-v), не лишняя ли тут или vSum или vAverage?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 24 2008, 04:54
Сообщение #52


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Rst7 @ Feb 23 2008, 22:18) *
Мне другой вопрос не ясен. Нафига 2 переменных в структуре? Ведь Y=Y*(1-k)-k*v <=> Y=Y-k*(Y-v), не лишняя ли тут или vSum или vAverage?

Для удобства пользования и для минимизации вычислений.
Если хранить только vSum то вычислять Average придется как минимум 2 раза. Первый раз при апдейте АЦП, второй раз при использовании.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 24 2008, 10:40
Сообщение #53


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Все... Туплю. Уже и ответ пространный написал, хорошо хоть отправить не бухнул, вовремя дошло. Просто хранится Y/k (k<1, конечно), а не Y. В младших битах - просто дробная часть...
Хотя, тут конечно, классическая дилемма время/память - или лишняя переменная или 2 раза считать.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 24 2008, 18:47
Сообщение #54


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Feb 23 2008, 04:10) *
Я конечно не знаю вашей задачи полностью и возможно у вас есть некие строгие требования к сохранению фазы сигнала поэтому нужен КИХ, а я не брезгую БИХ'ом - ибо эффективней с т.з. памяти..
У меня скользящее по восьми измерениям занимает 2* U16 данных и кот наплакал кода.
итого 4 канала - 16 байт:
код для усреднения по 8-ми точкам:
Я тоже пользуюсь разными вариантами... иногда честное скользящее среднее
иногда экспоненциальный фильтр.
Цитата
Код
pChan->vAverage = (pChan->vSum + 4) >> 3;
pChan->vSum += val - pChan->vAverage;
и так тоже пользуюсь, тока для уменьшения рассчетов, я в таких случаях считаю что,
все вычисляется с коэфициентом (8 ну или сколько мы там решили),
тогда никагого оверхеда не происходит в принципе...
Цитата
Конечно, это не тот случай когда heap чем-то помог, но все же думать об экономии там где это возможно - стоит.
Ну вот я и хочу увидеть эту экономию, и особенно в сравнении с асм,
не, я конечно понимаю что для моих задач никакой экономии просто не будет,

Скажем так, хочу увидеть задачи (все таки контроллерные... хоть чуть...)
где использование heap будет нужным/оправданным..
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 24 2008, 19:50
Сообщение #55


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(singlskv @ Feb 24 2008, 22:47) *
Скажем так, хочу увидеть задачи (все таки контроллерные... хоть чуть...)
где использование heap будет нужным/оправданным..


Видете ли. Совершенно вам не в пику пишу. Это просто вопрос подходов. Вы его не приемлете (...хоть чуть..), а я считаю использование HEAP вполне оправданным.

Начнём с того, что использование HEAP на Си практически не увеличивает загрузку процессора. Поэтому вреда от этого никакого. А отсюда следует что его применение возможно везде. Теперь второе. В Си, в отличие от ASM, вы не контролируете память. Не знаю как правильнее выразится. Давайте лучше на примере.

Представьте, что вы пишите проект на ASM для которого чем больше свободной памяти - тем лучше. Вы его пишете и распределяете память вручную. Выделяете кусок в виде .byte, смотрите на стек и так далее. Задачу эту вы написали например на м64. Через некоторое время вы переползли на м640 где памяти вдвое больше. Вам придётся минимум пересчитать остаток свободной памяти и поменять одну константу. Можно так поступить и на Си. А можно использовать HEAP и тогда при переносе вам ничего менять не придётся. Не придётся ничего менять и пересчитывать также и при внесении изменений в проект . Но это пример, где можно или так или так.

Приведу пример, где я примененяю HEAP.

Представьте себе что контролер выполняет команды. Каждая команда имеет разную длину. От десятка байт до нескольких килобайт. Имеется очередь активных команд состоящая из 10 команд. Каждая команда имеет время старта и время смерти (начала и конца исполнения). То есть находящаяся в очереди команда может исполняться а может не исполняться, но после смерти удаляется из очереди и соответственно подгружается новая команда. Источник поступления команд может быть разный (причём одновременно) RS485, SD, Ethernet, Rf, EEPROM.

Здесь, на мой взгляд HEAP очень органично вписывается. Я делаю дефрагментацию (удаление дырки от выполненной команды), храню буфер активных команд (переменной длины) и буфер загружаемых команд (дабы к моменту когда понадобится новая команда - она уже находилась в контроллере - синхронизация загрузки и исполнения) тоже переменной длины. Чем более мощные команды я могу исполнять, тем больше возможности устройства. А это зависит от синхронизации загрузки и, соответственно от оптимальности распределения буферов внутри контроллера.
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 24 2008, 21:03
Сообщение #56


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ Feb 24 2008, 20:47) *
Скажем так, хочу увидеть задачи (все таки контроллерные... хоть чуть...)
где использование heap будет нужным/оправданным..

Ну так я ж выше привел такие примеры.
Везде где есть пакетная обработка - использование heap'a (точнее сказать использование динамической памяти) экономит расход.

Цитата
Здесь, на мой взгляд HEAP очень органично вписывается. Я делаю дефрагментацию (удаление дырки от выполненной команды), храню буфер активных команд (переменной длины)

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

плюсы - быстро, нет проблем с фрагментацией, простой менеджер памяти.
минусы - overhead на маленьких объемах, и ограничение по объему.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 24 2008, 22:23
Сообщение #57


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(SasaVitebsk @ Feb 24 2008, 22:50) *
Начнём с того, что использование HEAP на Си практически не увеличивает загрузку процессора.
Поэтому вреда от этого никакого. А отсюда следует что его применение возможно везде.
Увеличивает и очень прилично...
Я как бы понимаю необходимость использования heap например при загрузке картинки или
приеме пакета неизвестной длинны через Ethernet...
но для реалтайма непонимаю...
Цитата
Теперь второе. В Си, в отличие от ASM, вы не контролируете память. Не знаю как правильнее выразится.
Как это не контролирую ? Лично я контролирую, и это не сильно отличается от асм,
ну конечно printf, итд я просто не пользуюсь.
Цитата
Представьте, что вы пишите проект на ASM для которого чем больше свободной памяти - тем лучше. Вы его пишете и распределяете память вручную. Выделяете кусок в виде .byte, смотрите на стек и так далее. Задачу эту вы написали например на м64. Через некоторое время вы переползли на м640 где памяти вдвое больше. Вам придётся минимум пересчитать остаток свободной памяти и поменять одну константу. Можно так поступить и на Си. А можно использовать HEAP и тогда при переносе вам ничего менять не придётся. Не придётся ничего менять и пересчитывать также и при внесении изменений в проект . Но это пример, где можно или так или так.
Эээ..., ну просто стараюсь писать так чтобы перенос c одного чипа на другой заключался
только в переназначении пинов контроллера, обычно получаеться, правда иногда при переходе с более "старшего" чипа на младший приходится таймеры перенастраивать...
Цитата
Приведу пример, где я примененяю HEAP.
Представьте себе что контролер выполняет команды. Каждая команда имеет разную длину. От десятка байт до нескольких килобайт. Имеется очередь активных команд состоящая из 10 команд. Каждая команда имеет время старта и время смерти (начала и конца исполнения). То есть находящаяся в очереди команда может исполняться а может не исполняться, но после смерти удаляется из очереди и соответственно подгружается новая команда. Источник поступления команд может быть разный (причём одновременно) RS485, SD, Ethernet, Rf, EEPROM
Вот и я о том же, примерно, вопрос в том где это (использование heap) применимо/эфективно,
Вот для EEPROM, ИМХО, применимо/эфективно, только это не совместимо с использованием
стандартного для IAR _flash...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 25 2008, 13:23
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(singlskv @ Feb 25 2008, 02:23) *
Увеличивает и очень прилично...


Тогда давайте сначала с терминами определимся. HEAP - просто слово и всё. Термин. С момента как вам понадобилась вся память, независимо от того сколько её, - вы уже работаете с HEAP, нравится вам этот термин или нет. А вот как вы с ней работаете - это уже вопрос.
Если вы работаете через стандартные процедуры malloc/free (как я понял об этом идёт речь), то никаких накладных расходов практически нет так как malloc фактически проверяет есть ли у вас нужный объём и прибавляет к указателю на свободное место этот объём. А free просто записывает новое значение указателя (с контроллем). Поскольку процедуры эти - не ногодрыганье, то, очевидно, что это времени не отнимает.
Если вы не используете стандартный диспетчер памяти, то вам приходится городить свой. Явно или неявно. Если не явно, то, в простейшем случае, вам придётся один раз при инициализации выделить всю память и в процессе работы контролировать границу, куда залазить нельзя (кольцевой буфер). В более сложной реализации вам придётся определять размер объекта и т.д., что по сути и делает стандартный набор средств. В ещё более сложной реализации (дефрагментация) вам придётся реализовать свой диспетчер.

Теперь опять возвратимся к терминам. Итак мы работаем с HEAP но не хотим в этом признаваться. Тогда у нас несколько путей. 1) вписываем работу с памятью прямо в тексте проги, 2) используем процедуры с уникальным названием, 3) используем стандартные названия (даже если процедуры пишем сами).

По-моему, лучше 3 путь. Всё таки это опыт программеров и общие термины. А вообще, и это мне тоже очень нравится, Си очень демократичный язык. Возьмите в своём проекте напишите процедуру malloc и вот вам стандартная и в тоже время более качественная (с вашей точки зрения) реализация.


PS: Не вижу ни каких проблем и с EEPROM и c FLASH. Можно сделать всё что угодно. Вплоть до реализации потоков и файлов. Или параллельной кучи и даже общей кучи. В винде вон часть памяти на винте находится территориально. А у меня, например EEPROM внешняя и внутренняя объёденены в общее пространство.
Всё в ваших руках. Не нравится - перепиши.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Feb 26 2008, 09:29
Сообщение #59


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



По-моему, с heap основная проблема в том, как рассчитать максимальную загрузку. И что делать, если память кончилась - допустимо ли отклонить запрос. Например, пример defunct - в 99% времени обработчику нужен только 1 пакет. Если таких обработчиков 5 - то какая куча нам нужна? На 10 пакетов? В этом случае мы не выигрываем по сравнению со статическим выделением памяти. А если, к примеру, на 6 пакетов - то что делать в ситуации, когда пакетов 7. Или можно доказать, что ни в один момент времени не будет больше 6 пакетов...
Следующий нюанс - если вы храните объекты разного размера, то можно получить ситуацию, когда из-за фрагментации невозможно будет разместить новый объект при наличии значительного кол-ва свободной памяти. Тут по-ходу придется мастерить что-то свое, стандартные механизмы работы с кучей не подойдут.
Лично я использую "самописную" кучу для пользовательского интерфейса - например, есть основной экран, из него можно попасть в меню, из него - в другое меню, оттуда - в настройку параметра, из нее иногда - в настройку еще одного параметра. При этом объекты уничтожаются в порядке, обратном созданию, соответственно реализация очень проста и нет фрагментации.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 26 2008, 10:39
Сообщение #60


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Непомнящий Евгений @ Feb 26 2008, 12:29) *
..............................
Примерно это я и имел в виду.
Просто в моих задачах выгоднее статически выделять память.
А про накладные расходы по работе с кучей я имел в виду не момент выделения памяти,
там действительно все быстро в случае если ее хватает и есть непрерывный кусок нужного
размера, а вопрос по сборке мусора после произвольных выделений/освобождений памяти,
и вот там совсем все не быстро/просто.
Go to the top of the page
 
+Quote Post

5 страниц V  « < 2 3 4 5 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 00:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01552 секунд с 7
ELECTRONIX ©2004-2016