- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我查看 Atmel 软件框架中的一些驱动程序实现时,我遇到了几种使用内存屏障的情况。
障碍定义:
#define barrier() asm volatile("" ::: "memory")
示例 1(中断辅助函数):
static inline void cpu_irq_restore(irqflags_t flags)
{
barrier();
SREG = flags;
}
这个障碍对我来说很有意义。由于 cpu_irq_restore 是隐式内联的,因此它可以防止关键(从执行顺序角度来看)SREG 分配从实际函数调用位置重新排序。
作为旁注:SREG
被定义为特殊功能寄存器,定义为:
#define _SFR_MEM8(mem_addr) (*(volatile uint8_t *)(mem_addr))
示例 2(来自 AVR TWI 驱动程序):
static inline status_code_t twim_release(void)
{
/* First wait for the driver event handler to indicate something
* other than a transfer in-progress, then test the bus interface
* for an Idle bus state.
*/
while (OPERATION_IN_PROGRESS == transfer.status);
while (! twim_idle(transfer.bus)) { barrier(); }
status_code_t const status = transfer.status;
transfer.locked = false;
return status;
}
但是,我不清楚第二个用例。编译器可以通过什么方式优化该代码,使其在没有 barrier()
的情况下中断?
阅读 this article 后,我想我了解了软件内存障碍背后的基本推理。 .
在第二个示例中使用屏障的原因是什么?
最佳答案
twim_idle 函数可能会执行类似读取 TWI 相关特殊功能寄存器的值并检查其中某些位的操作。如果没有屏障,危险在于编译器可能会优化该寄存器的读取并将其移至第二个循环之前。那么第二个循环的行为将如下所示:
bool idle = twim_idle(transfer.bus);
while (!idle);
这是一种优化,可以使循环更快,并且对于读取普通变量是有效的,但在这种情况下显然会导致问题。在循环中放置障碍应该可以防止优化发生。
实际上,您不需要内存屏障,因为所有特殊功能寄存器都使用 volatile
关键字进行限定,因此编译器不会尝试缓存对它们的访问。
关于c - Atmel 驱动程序和 GCC 内存屏障用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37916566/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!