jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба есть пакет с данными 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) вопрос какой способ быстрее? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба вопрос какой способ быстрее? Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все. так что ли? if(*((uint32_t*)new_packet) != *((uint32_t*)old_packet)) а что, за кулисами происходит не одно и то же? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба Ну, для начала желательно знать, что за ядро. То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба так что ли? 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 зависит от вашего компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 (изменено) · Жалоба Ну, для начала желательно знать, что за ядро. То, что предложил ув. 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 . к тому же что может быть невыравненно в массиве? ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера. Изменено 15 декабря, 2015 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба функция принимает массив 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]) да и ошибку допустить будет сложнее в первом случае, вот и вся премудрость. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t. допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2])) и так далее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба Ну, для начала желательно знать, что за ядро. Надо, но не по другой причите о которой тоже сказали. То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра. Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо. Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t. НАЧАЛО массива по любому будет выравнено. Но в общеем случае, то есть ВСЕГДА :), нужно преобразовывать к указателю на структуру и работать с элементеми. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 (изменено) · Жалоба Надо, но не по другой причите о которой тоже сказали. Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо. НАЧАЛО массива по любому будет выравнено. Но в общеем случае, то есть ВСЕГДА :), нужно преобразовывать к указателю на структуру и работать с элементеми. так какой метод МАКСИМАЛЬНО хорош по вашему мнению? меня интересует СКОРОСТЬ исполнения. :) Изменено 15 декабря, 2015 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2])) и так далее. Нет, это фигня. В общем случае НЕЛЬЗЯ. так какой метод МАКСИМАЛЬНО хорош по вашему мнению? меня интересует СКОРОСТЬ исполнения. :) Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 (изменено) · Жалоба Нет, это фигня. В общем случае НЕЛЬЗЯ. Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять? а как не фигня? какая структура. у меня функция принимает массив 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 а не как структуру Изменено 17 декабря, 2015 пользователем Herz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба какая структура. у меня функция принимает массив uint8_t.Ну так преобразуйте в структуру. На что в С дано приведение типов? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба какая структура. у меня функция принимает массив uint8_t. 1) Не массив, а УКАЗАТЕЛЬ на массив 2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры. 3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба 1) Не массив, а УКАЗАТЕЛЬ на массив 2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры. 3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно? и все это для того чтобы сравнить неколько переменных? мне кажется быстрее уж сделать тем же memcmp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться