Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача структуры в функцию.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
Поправте если ошибаюсь.

Если я передам структуру by value
Код
void MyFunc (MyStruct my_struct)

то копия ляжет на стак и с ней ф-ция будет работать.

А если я передам структуру by reference
Код
void MyFunc (MyStruct *my_struct)

то ф-ция будет работать непосредственно со структурой.

А что со скоростью доступа - быстрее by value?
jcxz
Цитата(Jenya7 @ Feb 28 2018, 16:52) *
то копия ляжет на стак и с ней ф-ция будет работать.

Не факт. Зависит от размера структуры. Если структура влезает в два регистра, то IAR вроде как может её в регистрах передавать.

Цитата(Jenya7 @ Feb 28 2018, 16:52) *
А что со скоростью доступа - быстрее by value?

"Открыть асм и посмотреть" - так точно будет быстрее чем даже написать в форум. laughing.gif
Jenya7
Цитата(jcxz @ Feb 28 2018, 19:56) *
Не факт. Зависит от размера структуры. Если структура влезает в два регистра, то IAR вроде как может её в регистрах передавать.


"Открыть асм и посмотреть" - так точно будет быстрее чем даже написать в форум. laughing.gif

структура 200-300 байт.
про асм совсем забыл. посчитать инструкции?
jcxz
Цитата(Jenya7 @ Feb 28 2018, 16:59) *
про асм совсем забыл. посчитать инструкции?

Например так. А в IAR достаточно просто открыть окошко с регистрами и посмотреть на регистр CCSTEP.
Jenya7
Цитата(jcxz @ Feb 28 2018, 20:01) *
Например так. А в IAR достаточно просто открыть окошко с регистрами и посмотреть на регистр CCSTEP.

да. есть такой регистр. а что он показывает?
jcxz
Цитата(Jenya7 @ Feb 28 2018, 17:07) *
да. есть такой регистр. а что он показывает?

А Вы попробуйте пошагать по инструкциям и функциям и понаблюдать за ним. Узнаете много нового. laughing.gif
Только предварительно полезно установить галку на пункте "запрещать прерывания при шагании" в пункте меню "J-Link" IAR-а.
Jenya7
Цитата(jcxz @ Feb 28 2018, 20:08) *
А Вы попробуйте пошагать по инструкциям и функциям и понаблюдать за ним. Узнаете много нового. laughing.gif
Только предварительно полезно установить галку на пункте "запрещать прерывания при шагании" в пункте меню "J-Link" IAR-а.

а у меня ST-LINK там нет такого

CCSTEP все время 0.
jcxz
Цитата(Jenya7 @ Feb 28 2018, 17:19) *
CCSTEP все время 0.

Печалька. J-Link - круче! sm.gif
Регистр этот показывает сколько прошло тактов CPU за время шага. Он очень пользителен для профилирования кода.
Можно попробовать его вбить вручную в окно Watch: DWT.CYCCNT. Только предварительно его надо включить в модуле DWT.
Jenya7
Цитата(jcxz @ Feb 28 2018, 20:26) *
Печалька. J-Link - круче! sm.gif
Регистр этот показывает сколько прошло тактов CPU за время шага. Он очень пользителен для профилирования кода.
Можно попробовать его вбить вручную в окно Watch: DWT.CYCCNT. Только предварительно его надо включить в модуле DWT.

ой точно. можно ж на таймере такты отсчитать. спасибо.
а как все таки предпочтительней передавать - by value или by reference? или тут нет однозначного ответа? при условии что поля структуры не модифицируются.
jcxz
Цитата(Jenya7 @ Feb 28 2018, 17:38) *
ой точно. можно ж на таймере такты отсчитать. спасибо.
а как все таки предпочтительней передавать - by value или by reference? или тут нет однозначного ответа? при условии что поля структуры не модифицируются.

По значению, это что - Вы все 300 байт на стек копировать собрались??? 01.gif
А места там хоть хватит? Естественно быстрее передать указатель, чем копировать всё на стек. А если структура внутри не изменяется, то и в объявлении должно фигурировать const.

Цитата(Jenya7 @ Feb 28 2018, 17:19) *
а у меня ST-LINK там нет такого

PS: Вообще DWT.CYCCNT находится в ядре. Т.е. - не зависит от используемого эмулятора. Да и у Вас он показывается, только всё время ==0. Значит видимо выключен. Нужно его просто включить, найдя соответствующий бит в регистрах конфигурирования DWT. А J-Link видимо сам его включает.
Jenya7
Цитата(jcxz @ Feb 28 2018, 20:56) *
По значению, это что - Вы все 300 байт на стек копировать собрались??? 01.gif
А места там хоть хватит? Естественно быстрее передать указатель, чем копировать всё на стек. А если структура внутри не изменяется, то и в объявлении должно фигурировать const.


PS: Вообще DWT.CYCCNT находится в ядре. Т.е. - не зависит от используемого эмулятора. Да и у Вас он показывается, только всё время ==0. Значит видимо выключен. Нужно его просто включить, найдя соответствующий бит в регистрах конфигурирования DWT. А J-Link видимо сам его включает.

я понял. стек у меня на всякий случай 2К. а структура в этой ф-ции не модифицируется, а в другом месте поля могут измениться.
DWT таки выключен, надо вручную включать.
x893
Можно просто запустить в симуляторе и посмотреть в окне Disassembler.
Вопрос просто не возник бы после этого.
Jenya7
Цитата(x893 @ Feb 28 2018, 21:42) *
Можно просто запустить в симуляторе и посмотреть в окне Disassembler.
Вопрос просто не возник бы после этого.

тоже идея.
Baser
Цитата(Jenya7 @ Feb 28 2018, 18:18) *
структура в этой ф-ции не модифицируется, а в другом месте поля могут измениться.

Если структура и стек расположены в памяти с одинаковым доступом,
и если структура во время работы вашей функции в другом месте не меняется (в прерывании или из-за работы РТОС),
то ессно нужно передавать указатель и работать с оригиналом.

Если структура может меняться, то нужно обеспечивать разграничение доступа.
Причем простая передача копии структуры в функцию этой проблемы не решает.

А если доступ к стеку и памяти структуры разный по времени, то тут уже считать нужно.
dimka76
Цитата(Jenya7 @ Feb 28 2018, 17:52) *
то копия ляжет на стак и с ней ф-ция будет работать.


Ключевое слово копия.
На копирование необходимо затратить какое-то время.
А передача указателя - вычисление адреса структуры произойдет на этапе компиляции.
Unfog
1. Если нужно работать с копией: void foo(type obj). При этом будет вызван конструктор копирования, со всеми вытекающими (стек, скорость).
2. Если нужно работать с исходным объектом:
а) Объект можно/нужно изменять: void foo(type* obj)
б) Объект нельзя изменять: void foo(const type& obj)

При sizeof(type) больше разрядности процессора/контроллера второй вариант быстрее первого, т. е. нужно передать только адрес объекта.
Jenya7
А если я передаю адрес объекта я могу в другой функции модифицировать объект? Если это однопоточная система, мютексы не нужны как я понимаю.
Код
void main (void)
{
    while (1)
    {
         ModifyObject(MyStruct *my_struct);

          ProcessObject(MyStruct *my_struct);
    }
}
Unfog
Да, можно. Но нужно помнить про прерывания.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.