【问题标题】:How do I write a memory barrier for a TMS320F2812 DSP?如何为 TMS320F2812 DSP 编写内存屏障?
【发布时间】:2012-10-09 09:44:36
【问题描述】:

我查看了 TI C/C++ 编译器 v6.1 用户指南 (spru514e),但没有找到任何内容。

asm 声明在这方面似乎没有提供任何内容,手册甚至警告不要更改变量值 (p132)。未实现用于声明对变量的影响的 GNU 扩展 (p115)。

我也没有找到任何内存屏障的内在属性(例如 Keil 的 armcc 中的 __memory_changed())。

搜索网络或 TI 论坛也一无所获。

还有其他提示如何进行吗?

【问题讨论】:

  • 排序要求似乎只是关于编译器优化和调度。我不认为这可以通过将asm 语句移出到静态内联函数中来解决,返回您要更新的值?
  • wiki 表示编译器不支持Atomic Builtins。可能,您唯一的希望是 volatile 访问不会重新排序。您可能需要插入一些 nop 以避免不受保护的流水线冲突,如 CPU 和指令集参考指南的流水线章节中所述。如果你有多个 CPU,事情会变得更糟。
  • @unixsmurf 我不想在汇编中做任何事情。一个空的内联汇编语句说它修改了内存只是在 gcc 中做内存屏障的一种方法。
  • @Alexey Frunze 感谢您的链接,我不知道 gcc 有明确的内存屏障('__sync_synchronize()')。至于 TI 编译器,volatile 似乎可以工作,但我想避免它,因为它会阻止太多的编译器优化。
  • @starblue 另外,我记得我们使用asm("")(带空字符串)语句强制编译器完成所有后期效果。它很早以前就与非常旧版本的 TI 编译器一起使用。但是你可以检查一下,也许它仍然有效。只需将这个asm(""); 放在需要的读写之前和之后。

标签: c concurrency memory-barriers texas-instruments ti-dsp


【解决方案1】:

内存屏障与内存访问的顺序有关,但您还必须确保值不会留在寄存器中,而是完全写入内存。

使用 TI 编译器强制执行此操作的唯一方法是使用 volatile

请注意,volatile 虽然是变量的修饰符,但在其实现中不是关于变量本身(即它的内存),而是关于对这个变量的所有访问。 因此,如果您想避免优化太少的影响,请编写您的程序,以便只有一些变量访问是易失的。

为此,请正常声明您的变量,并仅在您想要强制读取或写入变量时添加volatile。 您可以像这样使用辅助函数:

inline void force_write(int *ptr, int value)
{
    *(volatile int *)ptr = value;
}

或者使用这个从 Linux 偷来的漂亮宏,可用于读/写和所有类型:

#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
...
if (ACCESS_ONCE(ready) != 0)
    ACCESS_ONCE(new_data) = 42;

(这个名字有历史原因;最好叫它FORCE_ACCESS。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 2011-03-30
    • 1970-01-01
    • 2014-02-17
    • 2015-12-06
    相关资源
    最近更新 更多