misyachniy 0 29 мая, 2019 Опубликовано 29 мая, 2019 · Жалоба Взял за основу пример UDP обмена на плате Spartan 6. Используюя накопленный опыт, решил использовать струтуру в которой не нужно выравнивания (надеюсь ;-)) // структура короткого запроса typedef struct{ int cmd; // код команды/запроса int addr; // адрес обращения int data; // данные для записи/чтения unsigned int crc; }SHORT_CMD; Обрабатываю пакеты под отладчиком в плате. 1) Копирую нужную часть memcpy(&short_cmd, udp_packet, sizeof(SHORT_CMD)); 2) Подсчитываю контрольную суссу, она сходиться 3) По коду запроса вызываю функцию обработки В отладчике видно что поле data имеет значение 0xAA 4)Захожу в функцию Параметр data передается в функцию с перестановкой байт. addr, наверное тоже, но не видно так как он равен нулю. Настройки процессора следующие: Допустим можно попутать big/little endian. Почему компилятор корректно извлекает из структуры число, а передает его в функцию некорректно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 29 мая, 2019 Опубликовано 29 мая, 2019 (изменено) · Жалоба Был бы Cи на линуксе, я бы сходу сказал, что структуры, передаваемые по сети нужно упаковывать с помощью директивы pragma pack, иначе компилятор все это дела выравняет сам под кеш линию и в сеть уйдет черти что, это достаточно серьезный источник проблем. Потом бы разбирался дальше. Изменено 29 мая, 2019 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
misyachniy 0 29 мая, 2019 Опубликовано 29 мая, 2019 · Жалоба 33 minutes ago, new123 said: Был бы Cи на линуксе, я бы сходу сказал, что структуры, передаваемые по сети нужно упаковывать с помощью директивы pragma pack, иначе компилятор все это дела выравняет сам под кеш линию и в сеть уйдет черти что, это достаточно серьезный источник проблем. Потом бы разбирался дальше. Сеть здесь ни при чем. Создается впечатление, что отображение в отладчике и передача параметров в функцию не одно и тоже Такая передача не работает result_cmd = parser_put(short_cmd.addr, short_cmd.data); Если объявить промежуточные переменные,то работает int answer_addr, answer_data; answer_addr = short_cmd.addr; answer_data = short_cmd.data; result_cmd = parser_put(answer_addr, answer_data); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryR 0 11 июня, 2019 Опубликовано 11 июня, 2019 · Жалоба On 5/29/2019 at 9:49 AM, misyachniy said: Допустим можно попутать big/little endian. Почему компилятор корректно извлекает из структуры число, а передает его в функцию некорректно? Я так понимаю, что вы жалуетесь на parser_put(). Я вижу, что функция parser_put принимает отдельные аргументы, а на экране отладчика у вас показаны поля некой структуры rx_packet, которая непонятно какое отношение имеет к этой функции. On 5/29/2019 at 2:09 PM, new123 said: Был бы Cи на линуксе, я бы сходу сказал, что структуры, передаваемые по сети нужно упаковывать с помощью директивы pragma pack, иначе компилятор все это дела выравняет сам под кеш линию и в сеть уйдет черти что, это достаточно серьезный источник проблем. Потом бы разбирался дальше. Во-первых язык программирования Си никак не связан с ОС Линукс, и результаты компиляции не зависят от того, применяется она или нет. Затем, pragma pack - это зло, которое делает программы непереносимыми. А в данном случае оно на структуру, состоящую из одних целых, никакого влияния не окажет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 11 июня, 2019 Опубликовано 11 июня, 2019 (изменено) · Жалоба 2 hours ago, DmitryR said: Затем, pragma pack - это зло, которое делает программы непереносимыми а как на переносимом коде решить вопрос выравнивания структур? Чтобы, например, в кабель, уходили как есть. 2 hours ago, DmitryR said: А в данном случае оно на структуру, состоящую из одних целых, никакого влияния не окажет. на разных процах с разной кеш линией окажет 100% (выровняет нулями в конце разного кол-ва). Это сейчас процы унифицировались и стали делать под одну кеш линию. Раньше было хуже с этим. Изменено 11 июня, 2019 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryR 0 11 июня, 2019 Опубликовано 11 июня, 2019 · Жалоба 48 minutes ago, new123 said: а как на переносимом коде решить вопрос выравнивания структур? Чтобы, например, в кабель, уходили как есть. на разных процах с разной кеш линией окажет 100% (выровняет нулями в конце разного кол-ва). Это сейчас процы унифицировались и стали делать под одну кеш линию. Раньше было хуже с этим. Для этого есть много вариантов, от битовых полей до C++. Что же касается кэша - добивать нолями каждую структуру до размера его линии не только бессмысленно, но и вредно, и конечно ни один компилятор этого не делает. Да и не может, потому что кэши бывают внезапно разными даже у процессоров с одним и тем же набором инструкций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 11 июня, 2019 Опубликовано 11 июня, 2019 · Жалоба 58 minutes ago, new123 said: а как на переносимом коде решить вопрос выравнивания структур? Чтобы, например, в кабель, уходили как есть. никак, для каждого компилятора надо будет бороться с его собственными прагмами/атрибутами. но можно некрасиво руками (макросы htonl / шаблоны с++) перекладывать побайтно приводя к нужной endianess. Quote 4)Захожу в функцию Параметр data передается в функцию с перестановкой байт. ну так указано же big endian, вот константа 0x000000AA (LE) и легла в память как 0xAA000000. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 11 июня, 2019 Опубликовано 11 июня, 2019 · Жалоба 57 minutes ago, DmitryR said: , и конечно ни один компилятор этого не делает. я подозреваю мы о разном говорим. О каких то разных компиляторах. Вы наверное про какой то внутренний компиль Xilinx. А так, что gcc, что intel ровняет структуры под кеш линии только в путь. Под 32, либо 64. Давно работаю с сетями, это вообще стандартная проблема, когда явно не указал, компилятор выровнял и в кабель ушли совершенно не пригодные для приема данные. 1 hour ago, DmitryR said: до размера его линии не только бессмысленно, ровнять имеет смысл в узких задачах. Когда очень критичен показатель промаха по кешу и важна простота работы с память в "ручном" режиме. Не зря же разрабы intel и boost создают свои аллокаторы памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
misyachniy 0 19 июня, 2019 Опубликовано 19 июня, 2019 · Жалоба On 6/11/2019 at 1:24 PM, _pv said: ну так указано же big endian, вот константа 0x000000AA (LE) и легла в память как 0xAA000000. Я для проверки использую передачу 0x12345678 и по ней лучше видно как переставляются данные. В данном случае, отладчик подавил лидирующие нули. У меня 0xAA0000, а не 0xAA000000. P.S. Честно говоря не пойму при чем здесь кэш. У меня процессор 32 бита, все данные стуктуры 32 бита. Что нужно выравнивать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться