Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

GCC_MEMORY_BARRIER() при AVR GCC
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=10955
Страница 1 от 1

Автор:  Nikola Kirov [ Нед Яну 06, 2013 10:41 pm ]
Заглавие:  GCC_MEMORY_BARRIER() при AVR GCC

/** Forces GCC to create a memory barrier, ensuring that memory accesses are not reordered past the barrier point.
* This can be used before ordering-critical operations, to ensure that the compiler does not re-order the resulting
* assembly output in an unexpected manner on sections of code that are ordering-specific.
*/
#define GCC_MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory");

Все пак въпреки обяснението не мога да схвана с сигурност какво трябва да прави този макрос на практика. Някой по навътре може ли да сподели смисъла ?

Автор:  palavrov [ Нед Яну 06, 2013 11:14 pm ]
Заглавие:  Re: GCC_MEMORY_BARRIER() при AVR GCC

На практика това кара компилатора да махне всички кеширани променливи в регистри и т.н. и да ги запише в паметта. Използва се предимно за синхронизация при multithreading, task switching, и т.н.
Малко по в детайли - при GCC C inline assembly може да се окаже в кои регистри са входни, кои изходни и кои се развалят, като в последния случай може да се каже memory т.е. правят се какви да е промени и в паметта, което кара компилатора да вдигне ръце около този инлайн. В мулти процесорни системи това не е достатъчно - там трябва да се инвалидира и cpu caches, съответно MEMORY_BARRIER е по сложен. В сорсовете на Linux ядрото и разни RTOS има много примери ако ти се задълбава.

Автор:  miro_atc [ Пон Яну 07, 2013 10:48 am ]
Заглавие:  Re: GCC_MEMORY_BARRIER() при AVR GCC

Е то за AVR няма чак такива кешове и мултипроцесорни истории...

Просто ГЦЦ има оптимазиции, които могат да разбъркат кода както си искат. Спазва се само крайния резултат. Примерно имаш две променливи, в едната правиш сметки, сметки, сметки... и като свършиш вдигаш другата променлива като флагче. След като се изпълни целия код, флагчето ще е вдигнато и сметката ще е вярна. Това ти е гарантирано. Обаче не е гарантирана последователността, демек флагчето може да се вдигне и преди сметките да са свършели.
И ако имаш друг код, примерно прекъсване в таймер дето полира флагчето може да стане инфекция...

Единият вариант естествено е да направиш volatile променливите. Но ако имаш много променливи и всички да ги правиш volatile е кофти. Ще вържеш ръцете на оптимизациите. А другия вариант е с тия бариери. Тя ти гарантира, че всичко дето го има като сметки и работа с паметта ще бъде направено преди да почне да се изпълнява код след бариерата...

Между другото не е зле да сложиш volatile на (преди) asm-то... Ей тъй като навик просто. В случая нямаш код в асемблито, само бариерата. Но някъде ще сложиш код и ще се чудиш що не бачка. Просто асемблера също подлежи на оптимизации... а ти едва ли очакваш някай да ти бара асемблера ;-)

Автор:  Nikola Kirov [ Пон Яну 07, 2013 7:10 pm ]
Заглавие:  Re: GCC_MEMORY_BARRIER() при AVR GCC

Аха. Мерси. Изясни ми се. При IAR и другите компилатори се прави с volatile само. Иначе кода си е на Атмел от тяхния ASF.

Автор:  palavrov [ Пон Яну 07, 2013 8:12 pm ]
Заглавие:  Re: GCC_MEMORY_BARRIER() при AVR GCC

volatile има ефект само върху една променлива. А както Миро спомена не е добра идея всички променливи да са ти volatile. Memory barrier има ефект върху всички променливи. Въпреки, че съм хващал GCC все пак да си оставя разни променливи по регистри - играх си да видя дали ще успея да симулирам try ... catch на чисто C със set/long jump() - не става точно заради кешираните/оптимизирани променливи в регистри.

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/