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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> отследить изменение переменной.
Jenya7
сообщение Dec 15 2015, 10:14
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



есть пакет с данными uint8_t packet[20] . переменная uint32_t занимает 4 байта. соответственно если я хочу посмотреть изменилась ли переменная в следующей посылке я могу сделать так
Код
if (new_packet[0] != old_packet[0] || new_packet[1] != old_packet[1] || new_packet[2] != old_packet[2] || new_packet[3] != old_packet[3])

или так
Код
if(memcmp(new_packet, old_packet, 4) != 0)

вопрос какой способ быстрее?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 15 2015, 10:18
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Jenya7 @ Dec 15 2015, 12:14) *
вопрос какой способ быстрее?

Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все.





--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Dec 15 2015, 11:09
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(zltigo @ Dec 15 2015, 16:18) *
Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все.

так что ли?

if(*((uint32_t*)new_packet) != *((uint32_t*)old_packet))

а что, за кулисами происходит не одно и то же?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Dec 15 2015, 11:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Ну, для начала желательно знать, что за ядро.
То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 15 2015, 11:33
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(Jenya7 @ Dec 15 2015, 14:09) *
так что ли?

if(*((uint32_t*)new_packet) != *((uint32_t*)old_packet))

а что, за кулисами происходит не одно и то же?


Нет, разное происходит. При таком варианте у вас может быть проблема с невыровненным доступом.
Идеальный вариант - объявить упакованную структуру. которая разложит байты пакета согласно логического содержания, ну а дальше оперировать полями этой структуры.

Код
   __packed struct packet {
       ...
       uint32_t ref;
       ...
   };
  
   struct packet *old_packet;
   struct packet *new_packet;
  
   if (old_packet->ref != new_packet->ref)
   {
       do_stuff();
   }

__packed зависит от вашего компилятора.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Dec 15 2015, 11:37
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Dog Pawlowa @ Dec 15 2015, 17:32) *
Ну, для начала желательно знать, что за ядро.
То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра.

это Cortex-M3

Цитата(msalov @ Dec 15 2015, 17:33) *
Нет, разное происходит. При таком варианте у вас может быть проблема с невыровненным доступом.
Идеальный вариант - объявить упакованную структуру. которая разложит байты пакета согласно логического содержания, ну а дальше оперировать полями этой структуры.

Код
__packed struct packet {
       ...
       uint32_t ref;
       ...
   };
  
   struct packet *old_packet;
   struct packet *new_packet;
  
   if (old_packet->ref != new_packet-<ref)
   {
       do_stuff();
   }

__packed зависит от вашего компилятора.


функция принимает массив uint8_t . к тому же что может быть невыравненно в массиве?
ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера.

Сообщение отредактировал Jenya7 - Dec 15 2015, 11:40
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 15 2015, 11:41
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(Jenya7 @ Dec 15 2015, 14:37) *
функция принимает массив uint8_t . к тому же что может быть невыравненно в массиве?

Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t.

Цитата(Jenya7 @ Dec 15 2015, 14:37) *
ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера.

Будущему вам будет проще читать
Код
if (old_packet->ref != new_packet-<ref)

нежели
Код
if (new_packet[0] != old_packet[0] || new_packet[1] != old_packet[1] || new_packet[2] != old_packet[2] || new_packet[3] != old_packet[3])

да и ошибку допустить будет сложнее в первом случае, вот и вся премудрость.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Dec 15 2015, 11:45
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(msalov @ Dec 15 2015, 17:41) *
Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t.

допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда
if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2]))
и так далее.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 15 2015, 11:54
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Dog Pawlowa @ Dec 15 2015, 13:32) *
Ну, для начала желательно знать, что за ядро.

Надо, но не по другой причите о которой тоже сказали.
QUOTE
То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра.

Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо.


QUOTE (msalov @ Dec 15 2015, 13:41) *
Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t.

НАЧАЛО массива по любому будет выравнено.
Но в общеем случае, то есть ВСЕГДА sm.gif, нужно преобразовывать к указателю на структуру и работать с элементеми.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Dec 15 2015, 11:56
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(zltigo @ Dec 15 2015, 17:54) *
Надо, но не по другой причите о которой тоже сказали.

Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо.



НАЧАЛО массива по любому будет выравнено.
Но в общеем случае, то есть ВСЕГДА sm.gif, нужно преобразовывать к указателю на структуру и работать с элементеми.

так какой метод МАКСИМАЛЬНО хорош по вашему мнению?
меня интересует СКОРОСТЬ исполнения. sm.gif

Сообщение отредактировал Jenya7 - Dec 15 2015, 11:58
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 15 2015, 12:00
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Jenya7 @ Dec 15 2015, 13:45) *
допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда
if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2]))
и так далее.

Нет, это фигня. В общем случае НЕЛЬЗЯ.



QUOTE (Jenya7 @ Dec 15 2015, 13:56) *
так какой метод МАКСИМАЛЬНО хорош по вашему мнению?
меня интересует СКОРОСТЬ исполнения. sm.gif

Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Dec 15 2015, 12:07
Сообщение #12


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(zltigo @ Dec 15 2015, 18:00) *
Нет, это фигня. В общем случае НЕЛЬЗЯ.

Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять?

а как не фигня?
какая структура. у меня функция принимает массив uint8_t.

Код
tBleStatus aci_gatt_update_char_value(uint16_t servHandle,
                      uint16_t charHandle,
                      uint8_t charValOffset,
                      uint8_t charValueLen,  
                      const uint8_t *charValue)

вот сюда - uint8_t *charValue - я должен передать свой пакет.
и для сравнения я получаю его как uint8_t *charValue а не как структуру

Сообщение отредактировал Herz - Dec 17 2015, 11:58
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 15 2015, 12:15
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата
какая структура. у меня функция принимает массив uint8_t.
Ну так преобразуйте в структуру. На что в С дано приведение типов? sm.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 15 2015, 12:18
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Jenya7 @ Dec 15 2015, 14:07) *
какая структура. у меня функция принимает массив uint8_t.

1) Не массив, а УКАЗАТЕЛЬ на массив
2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры.
3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?




--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Dec 15 2015, 12:22
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(zltigo @ Dec 15 2015, 18:18) *
1) Не массив, а УКАЗАТЕЛЬ на массив
2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры.
3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?

и все это для того чтобы сравнить неколько переменных? мне кажется быстрее уж сделать тем же memcmp
Go to the top of the page
 
+Quote Post

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

 


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


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