ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
19 мая
1020521 Топик полностью
fk0, легенда (24.07.2020 01:19, просмотров: 752) ответил Гyдвин на Нет уж... Тысячи строк кода, драйверы, куски стороннего кода (та же FatFs) и пр. как то не способствуют выворачиванию всего наизнанку. А по этому топику: Cortex M3 (LPC17) имеет аппаратную побайтную адресацию, посему фтопку компилер, взомнивший себя шибко грамотным... Более ранняя версия работала "как в мудрых книгах написано" - привели указатель к void* или char*, вызывается предсказуемая библиотечная функция побайтного копирования (и все остальные из string.h). И
Говнокода. И не такие уж и тысячи. Практически всё что завелось не на x86 такого говнокода не содержит. Потому, что и MIPS, и ARM -- это аппаратное исключение при невыравненном обращении и дальше либо фиксация ошибки, либо программная эмуляция команды с невыравненным чтением-записью (очень не быстро...) И даже на современном x86 словить исключение при невыравненном обращении -- запросто (векторные инструкции). Ещё раз, повторю, упакованные структуры -- НЕ СТАНДАРТНАЯ ХЕРНЯ. 

Никто и не обещал что она может работать во всех возможных случаях, тем более кроссплатформенно. На самом деле случаи когда она работает исключительно узкие: когда ты непосредственно обращаешься к полям структуры руками. ВСЁ. Это такой хакерский способ сериализовать данные. Работать полноценно с таким контейнером -- невозможно, перекладывай в нормальную структуру. Только и (де)сериализовать совсем уж руками тоже не сложно.


Разумеется компилятор оптимизирует код. Работай он как в книгах написано, ты бы не получал такой скорости в первую очередь. Тут уже писали: printf заменяет на puts когда может, чтения по байтику заменяет на чтение словами (так в 4-8 раз быстрей!), разворачивает циклы, переставляет местами операции, да там много чего, и достаточно глубоко -- сам не придумаешь сходу. И разумеется все преобразования кода осуществляются так, чтоб код был эквиэвалентен, давал такой же результат, в той модели вычислительной машины в которой работает компилятор, а он не оперирует битами и байтами конкретной модели процессора, у него своя более высокоуровневая модель определённая стандартом языка. И в ней совершенно естественно, что если переменная имеет тип "указатель на int", то содержимое памяти можно прочитать как одно машинное слово целиком за одну операцию, а не как 4 отдельных байтика за 4 операции. Так же совершенно естественно не писать цикл, как у тебя в самодельном memcpy сделано было, а поскольку он заранее знает сколько байт копируется, то может сразу сгенерировать код копирующий N байт, и даже вместо call куда-то-там просто заинлайнить этот код в твою функцию в несколько машинных инструкций. Но ты ему под видом указателя на int подсунул нечто совершенно другое, другой тип данных, тип с alignas(1) вместо alignas(4). И компилятору тебе даже варнинг не показать, т.к. тип он сам знает (неправильный) и с его точки зрения всё ок. Потому, что вот этот функционал, упакованные структуры -- кривая недоделка. Типы он не изменяет и новые не вводит, но обращения к переменным по тем типам, с которыми они декларированы -- тоже невозможно.


Хочешь использовать упакованные структуры -- работай с ними совсем вручную. Но толку от того никакого не будет. У тебя будет медленный и неэффективный memcpy, медленное и неэффективное обращение к каждому элементу. И ради чего? Ради того, чтоб однажды её скопировать куда-то целиком, без "лишних" нулей? Причём медленной версией memcpy. Не проще ли работать с нормальной структурой, и только когда её нужно единожды скопировать (передать по каналу связи) -- "сжать" её, выкинувь лишние нули при сериализации? Тем более, что при этом можно задать нужную ширину каждого поля. А в самой структуре не пытаться делать 8 или 16-битные поля, так как 32-битный процессор с такими полями работает не эффективно, путём применения нескольких лишних инструкций на каждый чих.


Все твои "ранние версии" прекрасно работали на 8-битных процессорах и x86, на котором тянули лямку совместимости с говнокодом. Но время 8-битных процессоров и x86 уже ушло безвозвратно. В современном мире нужны несколько другие подходы.


PS: пример кода сериализации структуры: http://caxapa.ru/993200/

[ZX]