Arlleex 178 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 2 часа назад, VladislavS сказал: for(;;) { GPIOA->ODR ^= (1 << 5); GPIOC->ODR ^= (1 << 5) | (1 << 8) | (1 << 9); delay(); } Вот если бы его класс сам делал подобную оптимизацию (а это на плюсах, в отличи от си возможно), то тогда и можно было засчитывать победу. ... то C++ от такой "оптимизации" тупо сел бы в лужу, ибо это два разных кода, не находите? for(;;) { GPIOA->ODR ^= (1 << 5); GPIOC->ODR ^= (1 << 5); GPIOC->ODR ^= (1 << 8); GPIOC->ODR ^= (1 << 9); delay(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 1 час назад, Arlleex сказал: то C++ от такой "оптимизации" тупо сел бы в лужу, ибо это два разных кода, не находите? Не нахожу. Код автора статьи (без delay, он тут ни на что не влияет) я бы написал так. using LEDS = PinList<PA_5,PC_5,PC_8,PC_9>; for(;;) LEDS::toggle(); Что для STM32 в процессе компиляции превратиться во что-то такое for(;;) { // PA5 toggle if (GPIOA->ODR & (1<<5)) *((volatile uint16_t *)&GPIOA->BSRR+1) = (1<<5); else GPIOA->BSRR = (1<<5); // PC5,PC8,PC9 toggle GPIOC->BSRR = (((1<<5)|(1<<8)|(1<<9)) << 16) | (~GPIOC->ODR & ((1<<5)|(1<<8)|(1<<9))); } Естественно не в ODR ^=, ибо это неправильно. Ну и из-под ARM Compiler v6 будет как-то так MOVS r0,#0x14 MOVW r2,#0x320 MOVW r3,#0x818 MOVT r0,#0x4800 // R0 = &GPIOA->ODR MOV r12,#0x20 MOVT r2,#0x320 MOVT r3,#0x4800 // R3 = &GPIOC->BSRR main: // if (GPIOA->ODR & (1<<5)) LDR r1,[r0,#0x00] LSLS r1,r1,#26 ITE PL // GPIOA->BSRR = (1<<5) STRPL r12,[r0,#0x04] // *((volatile uint16_t *)&GPIOA->BSRR+1) = (1<<5); STRHMI r12,[r0,#0x06] // GPIOC->BSRR = (((1<<5)|(1<<8)|(1<<9)) << 16) | (~GPIOC->ODR & ((1<<5)|(1<<8)|(1<<9))); LDR r1,[r0,#0x800] AND r1,r1,#0x320 EORS r1,r1,r2 STR r1,[r3,#0x00] B main И никто в лужу не сел, как ни странно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 1 час назад, VladislavS сказал: Не нахожу. volatile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба Что volatile? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба GPIOC->ODR ^= (1 << 5) | (1 << 8) | (1 << 9); != GPIOC->ODR ^= (1 << 5); GPIOC->ODR ^= (1 << 8); GPIOC->ODR ^= (1 << 9); и упаси Господь, если бы оптимизация сводила второе к первому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба Задача - помигать четырьмя диодами, приведёнными в списке. На С вы решаете сами первым или вторым способом её решать. А на С++ я просто говорю "переключи состояние всех диодов из списка". Есественно, заменить первое<=>второе он не имеет права. Но сформировать одну операцию вместо трёх для решения задачи на этапе компиляции и есть джедайство. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 84 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба Эммм.. Вы спорте о том, как лучше ногами дрыгать? Я бы ещё понял, если бы разбирали какие-то архивысокие материи. Но это?... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба Нет, я не о том как лучше ногами дрыгать. Вы неправильно поняли. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 84 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба Тогда о чем? О том, как написать пицот погдготовительных строк, а в итоге получить ровно то же самое, что и непосредственная запись в одну строку? Зачем спорить об инструментах? Давно уже ясно, что и как работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 11 минут назад, EdgeAligned сказал: Тогда о чем? Об ошибочном заключении, что автор статьи получил сложным способом тот же результат и поэтому делать так не имеет смысла. Имеет, просто надо более сильное кунг-фу использовать, тогда результат будет лучше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 12 минут назад, EdgeAligned сказал: а в итоге получить ровно то же самое, что и непосредственная запись в одну строку? А потом перекинуть один из светодиодов на другой порт. И сравнить - сколько времени программиста займет такое перекидывание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 84 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба Которое в принципе даст снова то же самое. Ценой бОльшего кол-ва подготовительных портянок. Я все это, как вы изволили выразиться, кунг-фу знаю, посему и говорю, что ну не там и не для того оное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 1 час назад, VladislavS сказал: Но сформировать одну операцию вместо трёх для решения задачи на этапе компиляции и есть джедайство. Ну а откуда у компилятора будет право смешать volatile-доступы в один? На это он не имеет право, либо ему об этом нужно как-то явно сказать. Причем так явно, чтобы это было видно программисту при первом взгляде на исходник. Какой пример написал автор статьи - его дело, но раз он написал последовательные обращения к GPIOC, пусть они и останутся последовательными, а никак не оптимизированными. Я прекрасно понимаю, где Ваш замысел был бы весьма уместен. Например, у меня бывает так, что нужно перепаковывать биты портов в структуры обмена. Разумеется, там все хитросплетено. Если это делать Си-шными макросами, то для универсальности каждый описанный пин повлечет за собой программный доступ к соответствующему регистру, что есть неоптимальность. Поэтому приходится руками сначала считать все нужные регистры 1 раз, а затем по ним работать макросами. Но и там есть свои неудобства, когда какой-то пин переезжает куда-то или целая группа. Да и оптимизировать групповое выделение битов проблематично - чтобы, например, учитывать, что при "переезде" бита с одного порта на другой, тот образовал пару с несколькими другими и их можно объединить одной инструкцией UBFX, например. Вот здесь C++ был бы очень полезен (хотя я детально не знаю как это сделать) - пусть на вход некому шаблону давали список считанных volatile-регистров, а он уже знал, где какой бит есть и как их максимально оптимально перетасовать. Где-то была даже статья, где метадвижок проходился сначала по списку портов, потом по списку пинов, выявлял смежные пины и т.д. И то... Необходимость в таком шаблоне возникла лишь вследствие создания дюжины одинаковых по сути устройств, но разного исполнения по разводке печатной платы и конкретного типа МК. Будь оно такое одно, все эти чтения и перетасовка пинов сделались бы руками по мере написания соотв. драйвера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 мая, 2023 Опубликовано 23 мая, 2023 · Жалоба 12 минут назад, Arlleex сказал: Ну а откуда у компилятора будет право смешать volatile-доступы в один? Он их не совмещает, а изначально формирует так как вы описали во втором абзаце вашего сообщения. 12 минут назад, Arlleex сказал: Причем так явно, чтобы это было видно программисту при первом взгляде на исходник. Зачем? При взгляде на исходник должно быть видно ЧТО делает код, а не КАК. Часто вы кишки printf изучаете при его использовании? 12 минут назад, Arlleex сказал: Какой пример написал автор статьи - его дело, но раз он написал последовательные обращения к GPIOC, пусть они и останутся последовательными, а никак не оптимизированными. При такой постановке задачи и результата ноль. И выводы ложные. А реальная задача автора "мигать списком диодов". 12 минут назад, Arlleex сказал: Например, у меня бывает так, что нужно перепаковывать биты портов в структуры обмена. Ну это оно и есть. 12 минут назад, Arlleex сказал: где метадвижок проходился сначала по списку портов, потом по списку пинов, выявлял смежные пины и т.д. Именно так и делается. Именно поэтому нет совмещения volatile, а есть их оптимальное формирование. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться