Перейти к содержанию
    

отследить изменение переменной.

есть пакет с данными 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)

вопрос какой способ быстрее?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вопрос какой способ быстрее?

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

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

так что ли?

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, для начала желательно знать, что за ядро.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так что ли?

 

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 зависит от вашего компилятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, для начала желательно знать, что за ядро.

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

это Cortex-M3

 

Нет, разное происходит. При таком варианте у вас может быть проблема с невыровненным доступом.

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

 

 __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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера.

Будущему вам будет проще читать

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])

да и ошибку допустить будет сложнее в первом случае, вот и вся премудрость.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда

if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2]))

и так далее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, для начала желательно знать, что за ядро.

Надо, но не по другой причите о которой тоже сказали.

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

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

 

 

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

НАЧАЛО массива по любому будет выравнено.

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо, но не по другой причите о которой тоже сказали.

 

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

 

 

 

НАЧАЛО массива по любому будет выравнено.

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

так какой метод МАКСИМАЛЬНО хорош по вашему мнению?

меня интересует СКОРОСТЬ исполнения. :)

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда

if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2]))

и так далее.

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

 

 

 

так какой метод МАКСИМАЛЬНО хорош по вашему мнению?

меня интересует СКОРОСТЬ исполнения. :)

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

а как не фигня?

какая структура. у меня функция принимает массив 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

какая структура. у меня функция принимает массив uint8_t.
Ну так преобразуйте в структуру. На что в С дано приведение типов? :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

1) Не массив, а УКАЗАТЕЛЬ на массив

2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры.

3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Не массив, а УКАЗАТЕЛЬ на массив

2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры.

3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?

и все это для того чтобы сравнить неколько переменных? мне кажется быстрее уж сделать тем же memcmp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...