VladislavS 39 30 июня, 2018 Опубликовано 30 июня, 2018 · Жалоба Недавно в другой теме проскакивал вот такой код. По сути - копирование восьми uint16_t. cpld_regs[0] = ppm8s.state.rx.chanel[0].fv_att_h.fvatt; cpld_regs[1] = ppm8s.state.rx.chanel[0].fv_att_v.fvatt; cpld_regs[2] = ppm8s.state.rx.chanel[1].fv_att_h.fvatt;; cpld_regs[3] = ppm8s.state.rx.chanel[1].fv_att_v.fvatt; cpld_regs[4] = ppm8s.state.rx.chanel[2].fv_att_h.fvatt;; cpld_regs[5] = ppm8s.state.rx.chanel[2].fv_att_v.fvatt; cpld_regs[6] = ppm8s.state.rx.chanel[3].fv_att_h.fvatt;; cpld_regs[7] = ppm8s.state.rx.chanel[3].fv_att_v.fvatt; Который компилируется вот в это LDR.W R1,??DataTable6 LDRH R2,[R1, #+0] MOV R0,#+1610612736 STRH R2,[R0, #+0] LDRH R3,[R1, #+2] STRH R3,[R0, #+2] LDRH R2,[R1, #+4] STRH R2,[R0, #+4] LDRH R3,[R1, #+6] STRH R3,[R0, #+6] LDRH R2,[R1, #+8] STRH R2,[R0, #+8] LDRH R3,[R1, #+10] STRH R3,[R0, #+10] LDRH R2,[R1, #+12] STRH R2,[R0, #+12] LDRH R3,[R1, #+14] STRH R3,[R0, #+14] Зачем компилятор R2 и R3 чередует? IAR 8.30.1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 30 июня, 2018 Опубликовано 30 июня, 2018 · Жалоба А выделенное то зачем? Вы что-то говорили про перемежение инструкций для удаления штрафов LDR/STR. Могли бы озвучить, в чем там проблема? Если выполнить просто: LDR R2, [R1, #4] LDR R2, [R2] то вторая команда выполнится за 2 такта. Если же между ними вставить любую другую команду, не модифицирующую R2, то LDR R2, [R2] должна выполниться за 1 такт. Это следует из фразы: LDR [any] are pipelined when possible. This means that if the next instruction is an LDR or STR, and the destination of the first LDR is not used to compute the address for the next instruction, then one cycle is removed from the cost of the next instruction. из "ARM® Cortex®‑M4 Processor Technical Reference Manual" раздел "3.3.3 Load/store timings". Поэтому мой генератор кода использует в качестве рабочих два регистра - R2 и R3 с перемежением, чтобы убрать такие штрафы. Зачем компилятор R2 и R3 чередует? Здесь не знаю. А для какого это ядра? Мой генератор кода заточен для Cortex-M4. У него я не знаю необходимости в таком перемежении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 30 июня, 2018 Опубликовано 30 июня, 2018 · Жалоба Здесь не знаю. А для какого это ядра? Мой генератор кода заточен для Cortex-M4. У него я не знаю необходимости в таком перемежении. Тоже Cortex-M4, если точнее, то STM32F427. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 30 июня, 2018 Опубликовано 30 июня, 2018 · Жалоба Таким образом теряете детерминизм и гарантированность времени окончания пересылки, так какой прок экономить такты? Ваш пост настолько бессмысленен, что даже не знаю как ответить..... :wacko: На всякий случай: частоты ШИМ-ов для motor control обычно лежат где-то около 10-30 кГц. А для моего Cortex-M это однозначно - много тысяч тактов CPU на период ШИМа. Что как бы не сравнимо с 31 тактом. Не находите? Если вы дадите себе труд изучить работу любого DMA в режиме linked-list, то увидите, что длительность пересылки будет много больше указанных нескольких десятков тактов. Кроме всего прочего.... Тоже Cortex-M4, если точнее, то STM32F427. Не знаю. По-крайней мере TRM для CM4 в разделе "3.3.3 Load/store timings" о необходимости такого не говорит. Можете сами убедиться. Может в реализации CM4 от STM32 имеется какой-то баг, который фиксится таким образом? У себя я реализовал только оптимизацию чередованием инструкций указанную выше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 30 июня, 2018 Опубликовано 30 июня, 2018 (изменено) · Жалоба Поэтому мой генератор кода использует в качестве рабочих два регистра - R2 и R3 с перемежением, чтобы убрать такие штрафы. Точно. LDR первая же всегда 2 такта занимает. Зачем компилятор R2 и R3 чередует? По тем же самым причинам - снижение штрафов на LDR/STR. LDR [any] are pipelined when possible. This means that if the next instruction is an LDR or STR, and the destination of the first LDR is not used to compute the address for the next instruction, then one cycle is removed from the cost of the next instruction. Изменено 30 июня, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 30 июня, 2018 Опубликовано 30 июня, 2018 · Жалоба По тем же самым причинам - снижение штрафов на LDR/STR. LDR [any] are pipelined when possible. This means that if the next instruction is an LDR or STR, and the destination of the first LDR is not used to compute the address for the next instruction, then one cycle is removed from the cost of the next instruction. В том случае это не применимо: содержимое R2 и R3 не используется для вычисления адреса в следующих за ними командах. Посмотрите внимательнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 1 июля, 2018 Опубликовано 1 июля, 2018 · Жалоба Ваш пост настолько бессмысленен, что даже не знаю как ответить..... :wacko: На всякий случай: частоты ШИМ-ов для motor control обычно лежат где-то около 10-30 кГц. А для моего Cortex-M это однозначно - много тысяч тактов CPU на период ШИМа. Что как бы не сравнимо с 31 тактом. Не находите? Если вы дадите себе труд изучить работу любого DMA в режиме linked-list, то увидите, что длительность пересылки будет много больше указанных нескольких десятков тактов. Кроме всего прочего.... Я тоже не понял эту аргументацию. Понял только что вам как бы детерминизм в токовых контурах не важен. И что такое токовый контур похоже не знаете. Ну не в теме и не в теме. Что поделаешь. Продолжайте пилить динамику. :biggrin: А тему переназовите так - как мне сделать пересылку быстрее чем по linked-list поскольку в XMC4700 оказался скверный DMA. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 1 июля, 2018 Опубликовано 1 июля, 2018 · Жалоба Кстати, решил почитать внимательнее 3.3.2. Load/store timings из Cortex-M3 Technical Reference Manual. Там есть такие строки: LDR Rx!,[any] is not normally pipelined. That is, base update load is generally at least a two-cycle operation (more if stalled). However, if the next instruction does not require to read from a register, the load is reduced to one cycle. Non register writing instructions include CMP, TST, NOP, and non-taken IT controlled instructions. Что это вообще за инструкции такие с синтаксисом обратной записи в базовый регистр LDR Rx!,[any]? Для LDM понимаю, но чтобы для LDR... Опечатка в документации? Тоже вряд ли, ниже по тексту про LDM отдельно все сказано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 1 июля, 2018 Опубликовано 1 июля, 2018 · Жалоба Что это вообще за инструкции такие с синтаксисом обратной записи в базовый регистр LDR Rx!,[any]? Для LDM понимаю, но чтобы для LDR... Опечатка в документации? Тоже вряд ли, ниже по тексту про LDM отдельно все сказано. Видимо это инструкции вида: LDR Rx, [Ry], #z и LDR Rx, [Ry, #z]! PS: Кстати - Вы смотрите не последнюю ревизию ядра. В ревизии r2p1 для CM3 такого замечания уже нет - видимо исправили. Так что надо смотреть какая ревизия ядра у Вашего МК. А тему переназовите так - как мне сделать пересылку быстрее чем по linked-list поскольку в XMC4700 оказался скверный DMA. Так расскажите нам: в каком таком ядре идеальный DMA, умеющий загружать из ОЗУ описание следующего блока linked-list (которое как правило имеет размер в несколько слов) за 0 тактов? Видимо это ядро умеет мгновенно телепортировать в DMA содержимое ОЗУ без использования шин :biggrin: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 1 июля, 2018 Опубликовано 1 июля, 2018 · Жалоба Вы о чём? :wacko: Простые вопросы на самом деле бывают со сложными ответами. Особенно когда мозаика не складывается в общий узор. Я повторю свой вопрос - откуда мк читает программный код? Есть ли дополнительный код или инструкции которые должен выполнять мк в нативе, или программный код на мк в режиме эмуляции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 1 июля, 2018 Опубликовано 1 июля, 2018 · Жалоба Я повторю свой вопрос - откуда мк читает программный код? При наличии PSRAM в чипе странно было бы генерить код не в него. Хотя, от задачи зависит тоже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 2 июля, 2018 Опубликовано 2 июля, 2018 · Жалоба При наличии PSRAM в чипе странно было бы генерить код не в него. Хотя, от задачи зависит тоже. Конечно генерю в PSRAM. При генерации в обычную SRAM время выполнения увеличивается примерно в 2 раза. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 2 июля, 2018 Опубликовано 2 июля, 2018 (изменено) · Жалоба Конечно генерю в PSRAM. При генерации в обычную SRAM время выполнения увеличивается примерно в 2 раза. Как и предполагалось, для ответа простые вопросы нужно хорошо подумать. Повторюсь: Откуда мк начинает выполнять программный код сразу после аппаратного сброса. Общая функция этого кода, и что происходит дальше по алгоритму. Изменено 2 июля, 2018 пользователем AVI-crak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 3 июля, 2018 Опубликовано 3 июля, 2018 · Жалоба Откуда мк начинает выполнять программный код сразу после аппаратного сброса. Общая функция этого кода, и что происходит дальше по алгоритму. А откуда он после сброса может выполнять код, на Ваш взгляд? Конечно же из flash. И алгоритм его находится во flash-памяти. Но формирует опкоды для исполнения в PSRAM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 3 июля, 2018 Опубликовано 3 июля, 2018 · Жалоба А откуда он после сброса может выполнять код, на Ваш взгляд? Конечно же из flash. Правильный ответ считается решением задачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться