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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> многоканальная обработка, нюансы
Doka
сообщение Dec 6 2006, 15:53
Сообщение #1


Electrical Engineer
******

Группа: СуперМодераторы
Сообщений: 2 163
Регистрация: 4-10-04
Пользователь №: 778



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

Однако вызываться они могут поразному:
1. вызываемой процедуре передается номер канала (фактически - индекс массива структур)
2. вызываемой процедуре передается адрес указателя на структуру

интересен выбор оптимального способа в приложении использования на сигнальниках (архитектура TI C5000)
2й способ , как я понимаю позволяет не привязываться к массиву структур - это позволяет (при большом объеме контекста) размещать структуры в карте памяти с разрывом (если поиному не влазиют) либо в разные секции памяти.

какие еще достоинства/недостатки? (в т.ч. с возможным влиянием на производительность алгоритма)


--------------------
Блог iDoka.ru
CV linkedin.com/in/iDoka
Sources github.com/iDoka


Never stop thinking...........................
Go to the top of the page
 
+Quote Post
=GM=
сообщение Dec 6 2006, 17:21
Сообщение #2


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(Doka @ Dec 6 2006, 12:53) *
в ЦОС при переходе от одноканальных алгоритмов обработки даннных к многоканальным часто приходится иметь дело с контекстом канала - наиболее распространенный способ для этого - завести структуру, содержащий контекст обработки канала. и в программе использовать массив структур размерностью с число каналов.

Однако вызываться они могут по разному:
1. вызываемой процедуре передается номер канала (фактически - индекс массива структур)
2. вызываемой процедуре передается адрес указателя на структуру

интересен выбор оптимального способа в приложении использования на сигнальниках (архитектура TI C5000)
2й способ , как я понимаю позволяет не привязываться к массиву структур - это позволяет (при большом объеме контекста) размещать структуры в карте памяти с разрывом (если поиному не влазят) либо в разные секции памяти.

какие еще достоинства/недостатки? (в т.ч. с возможным влиянием на производительность алгоритма)


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

Но есть еще третий путь, самый быстрый - использовать DP-адресацию. Сам пользую, очень удобно.

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


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaTheProgramme...
сообщение Dec 7 2006, 03:56
Сообщение #3


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Цитата(=GM= @ Dec 6 2006, 16:21) *
Из двух предложенных я бы предпочел второй способ, не надо адрес вычислять, а в первом надо брать смещение, добавлять к индексу, проверять рамки...много возни.

Более того, если используется несколько вызовов подряд, например
Код
extern DATA data[];
/ **/
DATA *ptr = data+i;
foo(ptr);
if (isTRANSPARENT(mode)) bar(ptr);
if (isREPLY(mode)) doReply(ptr);
ptr->callBack(ptr);

то и адрес по индексу вычисляется один раз.
Цитата
Но есть еще третий путь, самый быстрый - использовать DP-адресацию. Сам пользую, очень удобно.

А это что за зверь?!
Цитата
А структура, имхо, сама по себе будет потреблять немного ресурсов, в смысле, чтобы добраться до элемента структуры.

Эт' как сказать. Один мой знакомый компилятор :-) транслирует выражение вроде ptr->subStruct->subField[i]++; в долгое вычисление адреса нужного слова, загружает его в регистр, прибавляет единицу... после чего снова вычисляет адрес - куда положить!!! Явное использование промежуточных указателей дало существенный прирост на таких, казалось бы простых, операциях...
Go to the top of the page
 
+Quote Post
=GM=
сообщение Dec 7 2006, 15:01
Сообщение #4


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(SasaTheProgrammer @ Dec 7 2006, 00:56) *
Более того, если используется несколько вызовов подряд, например
Код
extern DATA data[];
/ **/
DATA *ptr = data+i;
foo(ptr);
if (isTRANSPARENT(mode)) bar(ptr);
if (isREPLY(mode)) doReply(ptr);
ptr->callBack(ptr);

то и адрес по индексу вычисляется один раз.

Пример не наглядный, т.к. ваш указатель используется несколько раз подряд, счастлив ваш бог, и потом, вы сами явно указали процессору вычислять адрес по индексу один раз. А попробуйте хотя бы чередовать ptr1, ptr2, ptr1, ptr2 - увидите что будет(:-). Вот если бы вы передавали просто адрес, скажем адрес указателя на структуру, тогда другое дело, поскольку вычислять вообще ничего не надо!

К слову. Такое впечатление, что мы говорим на разных языках, и главное - пишем, я пишу в основном на ассемблере, поэтому и говорю, в основном, об адресации на языке ассемблера, а вы, похоже, говорите об адресации на си.

Цитата
Цитата

Но есть еще третий путь, самый быстрый - использовать DP-адресацию. Сам пользую, очень удобно.

А это что за зверь?!

direct addressing mode. Заносите в дп-регистр адрес страницы и обращаетесь к 64/128 переменным, используя DP-адресацию. Там для указания переменной надо писать @variable, например,

Код
   movl   @freq,acc   ;переслать 32-битную переменную в ячейку freq
   dec     @cont      ;скрутить счетчик
   tclr   @port,#bit  ;обнулить бит в порту



Цитата
Цитата

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

Эт' как сказать. Один мой знакомый компилятор :-) транслирует выражение вроде ptr->subStruct->subField[i]++; в долгое вычисление адреса нужного слова, загружает его в регистр, прибавляет единицу... после чего снова вычисляет адрес - куда положить!!! Явное использование промежуточных указателей дало существенный прирост на таких, казалось бы простых, операциях...

Ну вот, я был прав, компилер. Да будь он хоть трижды знакомый, с ним не договоришься, всё равно будет дурь переть(:-). И приходится вам, бедным сишникам, бороться не с программой и алгоритмом, а с дуроломным компилером и его разработчиками(:-). Здесь не надо отвечать, не хочу быть поджигателем очередной религиозной войны.

На ассемблере всё проще, есть такие виды адресации, как, скажем, XARn(ARm), одна команда, раз - и содержимое поля структуры у вас в кармане(:-).


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaTheProgramme...
сообщение Dec 8 2006, 02:40
Сообщение #5


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Цитата(=GM= @ Dec 7 2006, 14:01) *
Пример не наглядный, т.к. ваш указатель используется несколько раз подряд, счастлив ваш бог, и потом, вы сами явно указали процессору вычислять адрес по индексу один раз. А попробуйте хотя бы чередовать ptr1, ptr2, ptr1, ptr2 - увидите что будет(:-). Вот если бы вы передавали просто адрес, скажем адрес указателя на структуру, тогда другое дело, поскольку вычислять вообще ничего не надо!

Ну, так автор вопроса и спрашивал - что эффективней, адресация или индексирование по глобальному массиву. Во всяком случае, я понял вопрос именно так.
А что должно случиться при чередовании указателей? Или это косвенный намёк на особенности х51 (у кого ещё есть дп? smile.gif )?
Цитата
К слову. Такое впечатление, что мы говорим на разных языках, и главное - пишем, я пишу в основном на ассемблере, поэтому и говорю, в основном, об адресации на языке ассемблера, а вы, похоже, говорите об адресации на си.

Хмм... Думаю, что в данном контексте это несущественно. Сформулируем так: если обработка многостадийная, то адрес по индексу лучше вычислить один раз, а не передавать индекс в каждую процедуру. Независимо от языка и уровня реализации.
Цитата
Ну вот, я был прав, компилер. Да будь он хоть трижды знакомый, с ним не договоришься, всё равно будет дурь переть(:-). И приходится вам, бедным сишникам, бороться не с программой и алгоритмом, а с дуроломным компилером и его разработчиками(:-). Здесь не надо отвечать, не хочу быть поджигателем очередной религиозной войны.

На ассемблере всё проще, есть такие виды адресации, как, скажем, XARn(ARm), одна команда, раз - и содержимое поля структуры у вас в кармане(:-).

В общем случае не совсем так. На ассемблере действительно, чаще всего можно написать и компактней и эффективней. И в ряде случаев это приходится делать, получая очень существенный выиграш. Но наглядность и отлаживаемость кода резко падают, зато трудоёмкость растёт. А если код ещё и большой, то в конечном итоге компилятор с ЯВУ обеспечивает более эффективный код, чем одуревшая команда программистов biggrin.gif . Причём это происходит не только (а может быть и не столько) на "скромных" архитектурах вроде х51, но и на тяжеловозах АРМ (мой случай biggrin.gif ). Т.е. на самом деле важно найти "узкое место" - 5..10 процентов кода - и ассемблером их, ассемблером! Остальное так, как себе, любимому, проще, на эффективности это почти не скажется. И никаких войн!

Сообщение отредактировал SasaTheProgrammer - Dec 8 2006, 02:48
Go to the top of the page
 
+Quote Post
=GM=
сообщение Dec 8 2006, 12:59
Сообщение #6


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(SasaTheProgrammer @ Dec 7 2006, 23:40) *
Или это косвенный намёк на особенности х51 (у кого ещё есть дп? smile.gif )?

Цитата
Причём это происходит не только (а может быть и не столько) на "скромных" архитектурах вроде х51, но и на тяжеловозах АРМ (мой случай biggrin.gif ).

Вы несколько раз упомянули об архитектуре х51, это что i5051?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaTheProgramme...
сообщение Dec 8 2006, 23:33
Сообщение #7


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Цитата(=GM= @ Dec 8 2006, 11:59) *
Цитата(SasaTheProgrammer @ Dec 7 2006, 23:40) *

Или это косвенный намёк на особенности х51 (у кого ещё есть дп? smile.gif )?

Цитата
Причём это происходит не только (а может быть и не столько) на "скромных" архитектурах вроде х51, но и на тяжеловозах АРМ (мой случай biggrin.gif ).

Вы несколько раз упомянули об архитектуре х51, это что i5051?

Да. А резве подразумевалось что-то другое?
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Dec 9 2006, 00:55
Сообщение #8


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(=GM= @ Dec 8 2006, 12:59) *
Вы несколько раз упомянули об архитектуре х51, это что i5051?

Может все-таки классическое ядро 8051... Или я не в теме?..


--------------------
شامل
Go to the top of the page
 
+Quote Post
Doka
сообщение Dec 9 2006, 15:12
Сообщение #9


Electrical Engineer
******

Группа: СуперМодераторы
Сообщений: 2 163
Регистрация: 4-10-04
Пользователь №: 778



Цитата(Edmundo @ Dec 9 2006, 00:55) *
Может все-таки классическое ядро 8051... Или я не в теме?..

для присоединившихся:
изначально под C5000 я имел в виду С54хх и С55хх от TI.
интересовала реализация на языке Си.

хотя использование Си в какой-то мере подразумевает CPU-independent обсуждение.

благодаря ответам, вопрос прояснился.. теперь немного об автоматизации второго способа (через передачу указателя на адрес структуры):
если надо обрабатывать 32 канала, то в 1м способе просто могли организовывать цикл по 32, а переменную цикла передавать в функцию обработки ка кномер канала.
а в ситуации с передачей адреса указателя на структуру быть как?..
первое что приходит: заводить контекст канала всеже как _массив_ структур, а адрес структуры вычислять как:

Код
TYPE_OF_STRUC_CH_CONTEXT  struct_ch_context[32];
int *curr_struc_addr;
void  call_ch_process(int **paddr);
...
for (i = 0; i < 32;  i++)
{
  curr_struc_addr = struct_ch_context + i*sizeof(TYPE_OF_STRUC_CH_CONTEXT);  
  call_ch_process(*curr_struc_addr);
}


вот как-то так чтоли получается..


--------------------
Блог iDoka.ru
CV linkedin.com/in/iDoka
Sources github.com/iDoka


Never stop thinking...........................
Go to the top of the page
 
+Quote Post
SasaTheProgramme...
сообщение Dec 9 2006, 23:39
Сообщение #10


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Цитата(Doka @ Dec 9 2006, 14:12) *
хотя использование Си в какой-то мере подразумевает CPU-independent обсуждение.

Угу. Я, собственно, именно из таких соображений и отвечал.
Цитата
Код
TYPE_OF_STRUC_CH_CONTEXT  struct_ch_context[32];
int *curr_struc_addr;
void  call_ch_process(int **paddr);
...
for (i = 0; i < 32;  i++)
{
  curr_struc_addr = struct_ch_context + i*sizeof(TYPE_OF_STRUC_CH_CONTEXT);  
  call_ch_process(*curr_struc_addr);
}


вот как-то так чтоли получается..

НЕЕЕЕТ!!! Во-первых, не нужно умножать на размер структуры - компилятор сделает это сам - мы ведь о Си говорим? Т.е. это просто ошибка, указатель унесёт страшно даже подумать куда smile.gif .
Во-вторых, функция объявлена как принимающая указатель на указатель на int (откуда?!), а что ей передаётся в действительности?!

Сообщение отредактировал SasaTheProgrammer - Dec 10 2006, 00:09
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Dec 10 2006, 11:19
Сообщение #11


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Doka @ Dec 9 2006, 15:12) *
для присоединившихся:
изначально под C5000 я имел в виду С54хх и С55хх от TI.
интересовала реализация на языке Си.

хотя использование Си в какой-то мере подразумевает CPU-independent обсуждение.

благодаря ответам, вопрос прояснился.. теперь немного об автоматизации второго способа (через передачу указателя на адрес структуры):
если надо обрабатывать 32 канала, то в 1м способе просто могли организовывать цикл по 32, а переменную цикла передавать в функцию обработки ка кномер канала.
а в ситуации с передачей адреса указателя на структуру быть как?..
первое что приходит: заводить контекст канала всеже как _массив_ структур, а адрес структуры вычислять как:

Код
TYPE_OF_STRUC_CH_CONTEXT  struct_ch_context[32];
int *curr_struc_addr;
void  call_ch_process(int **paddr);
...
for (i = 0; i < 32;  i++)
{
  curr_struc_addr = struct_ch_context + i*sizeof(TYPE_OF_STRUC_CH_CONTEXT);  
  call_ch_process(*curr_struc_addr);
}


вот как-то так чтоли получается..

Я просто не встречал ядро i5051, а про С5000 понятно.

Но про код не понял -- почему не сделать так?

Код
TYPE_OF_STRUC_CH_CONTEXT  struct_ch_context[32];
void  call_ch_process(void *paddr);
...
for (i = 0; i < 32;  i++)
{
  call_ch_process(&struct_ch_context[i]);
}
...
void  call_ch_process(void *paddr)
{
    TYPE_OF_STRUC_CH_CONTEXT *pstruct = (TYPE_OF_STRUC_CH_CONTEXT *) paddr;
    pstruct->...
    ...
}

Или вам внутри call_ch_process нужно обязательно знать номер канала? Тогда проще добавить его как аргумент функции.


--------------------
شامل
Go to the top of the page
 
+Quote Post
Doka
сообщение Dec 10 2006, 11:52
Сообщение #12


Electrical Engineer
******

Группа: СуперМодераторы
Сообщений: 2 163
Регистрация: 4-10-04
Пользователь №: 778



Цитата(Edmundo @ Dec 10 2006, 11:19) *
Но про код не понял -- почему не сделать так?

Код
TYPE_OF_STRUC_CH_CONTEXT  struct_ch_context[32];
void  call_ch_process(void *paddr);
...
for (i = 0; i < 32;  i++)
{
  call_ch_process(&struct_ch_context[i]);
}
...
void  call_ch_process(void *paddr)
{
    TYPE_OF_STRUC_CH_CONTEXT *pstruct = (TYPE_OF_STRUC_CH_CONTEXT *) paddr;
    pstruct->...
    ...
}


Или вам внутри call_ch_process нужно обязательно знать номер канала? Тогда проще добавить его как аргумент функции.


за пример большое спасибо - просто почти не работал со структурами на Си - поэтому некий сумбур в голове.

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

еще такой исследовательский вопрос: когда я смотрел как это в принципе делают, то в нек-х случаях передают адрес указателя на структуру, а не указатель на структуру - для чего это может быть полезно? (единственно что напрашивается - возможность изменять само содержимое указателя)


--------------------
Блог iDoka.ru
CV linkedin.com/in/iDoka
Sources github.com/iDoka


Never stop thinking...........................
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Dec 10 2006, 14:11
Сообщение #13


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Doka @ Dec 10 2006, 11:52) *
за пример большое спасибо - просто почти не работал со структурами на Си - поэтому некий сумбур в голове.

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

еще такой исследовательский вопрос: когда я смотрел как это в принципе делают, то в нек-х случаях передают адрес указателя на структуру, а не указатель на структуру - для чего это может быть полезно? (единственно что напрашивается - возможность изменять само содержимое указателя)

У меня тоже только это напрашивается. Например если память под структуру выделяется (или перемещается) внутри этой функции.

А вообще про то, как организовывать многоканальную обработку, можно посмотреть в техасовском
XDAIS (если вы еще с ним не знакомы, конечно smile.gif). Сам стандарт в нашей лаборатории по разным причинам не пошел, но кое-какие идеи оттуда почерпнуть имхо можно.


--------------------
شامل
Go to the top of the page
 
+Quote Post
SasaTheProgramme...
сообщение Dec 10 2006, 14:35
Сообщение #14


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Начнём с конца.
Цитата(Doka @ Dec 10 2006, 10:52) *
еще такой исследовательский вопрос: когда я смотрел как это в принципе делают, то в нек-х случаях передают адрес указателя на структуру, а не указатель на структуру - для чего это может быть полезно? (единственно что напрашивается - возможность изменять само содержимое указателя)

Указатель передают в двух случаях. Во-первых, есть существеноое различие, для которого применяют специальные термины - "передача по ссылке"/"передача по значению". При "передаче по значению" функция получает свою копию данных, с которой можно делать всё что угодно. При "передаче по ссылке" любые изменения производятся в самих данных. Для коротких, неструктурных данных принято "передавать по ссылке" только те данные, которые нужно менять внутри функции (так, чтобы изменения были видны снаружи). В этом случае передача по ссылке - необходимые накладные расходы, на "разименование указателя" тратятся драгоценные такты.
Во-вторых, если речь идёт о структурах/объединениях/массивах (если передать в функцию массив, то на самом деле она получит указатель на первый элемент). Тут оказывается выгоднее передать указатель, чем запихивать структуру в регистры/стек. Т.е. простое программистское правило: "видишь передаваемый указатель - это точно out-параметер, возможно он ещё и in" в данном случае нарушается. Нужно очень вниматеьно обращатся с переданой таким образом структурой и обязательно (!!!) документировать в комментариях меняет ли функция что-либо, а если да - то какие поля.
Цитата
номер канала действительно желательно знать - ибо call_ch_process вызывает из себя процедуры, обработка в некоторых из них также завязана на контекст канала. Но номер канала планирую хранить как поле структуры , прописывая его при инициализации (ну а там уж передавать - либо номер канала, либо указатель на структуру).

Вся прелесть передачи указателя в том, что номер знать не нужно. Другим процедурам также передаётся указатель. Структуры могут вообще не лежать в массиве и нахождение указателя по номеру может быть нетривиальной задачей. Но она будет выполняться отлько один раз, "на самом верху" обработки.
Цитата
за пример большое спасибо - просто почти не работал со структурами на Си - поэтому некий сумбур в голове.

Это не структуры, это адресная арифметика. К этому нужно привыкнуть, да.
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Dec 10 2006, 16:18
Сообщение #15


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(SasaTheProgrammer @ Dec 10 2006, 14:35) *
Тут оказывается выгоднее передать указатель, чем запихивать структуру в регистры/стек. Т.е. простое программистское правило: "видишь передаваемый указатель - это точно out-параметер, возможно он ещё и in" в данном случае нарушается. Нужно очень вниматеьно обращатся с переданой таким образом структурой и обязательно (!!!) документировать в комментариях меняет ли функция что-либо, а если да - то какие поля.

Вопроса о передаче структуры "по значению" не стояло. Прочитайте вопрос внимательнее:
Цитата(Doka @ Dec 10 2006, 11:52) *
... адрес указателя на структуру, а не указатель на структуру ...


Цитата(SasaTheProgrammer @ Dec 10 2006, 14:35) *
Вся прелесть передачи указателя в том, что номер знать не нужно.

Нужно ли знать номер канала -- зависит от конкретной задачи. Передать его внутри структуры -- вполне красивое решение.


--------------------
شامل
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 14:35
Рейтинг@Mail.ru


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