我有一个 Parallax Propeller,它是一个 8 核微 Controller ,主频为 80MHz(即它比 Arduino 好很多,但并不惊人)。
我有几个变量需要在整个代码中访问 - 俯仰角和滚动角,等等(所有 float )。我的意图是将它们声明为 extern volatiles - 将仅设置在类中的全局变量,并且仅在其他地方读取(volatile存在,因为它是多核的)(extern因为这个类在一个单独的文件中)。
这是不好的做法吗?我试图避免使用函数调用它们,因为这只会减慢速度——所有变量都存储在主 ram 中,因此它们如何放置在那里无关紧要。有更好的方法吗?
假设使用函数调用它们会更好,这将如何完成?
volatile
保证编译器不会“优化掉对变量的访问”(经典示例是:
bool b = false;
while(!b) /* do nothing */;
编译器转向:
bool b = false;
bool tmp = !b; // tmp is really a processor register.
while(tmp) /* do nothing */;
由于循环中没有任何内容改变 b
,因此编译器执行此操作是一个有效的优化。
使用 volatile bool b;
将保证每次您在代码中“使用”b
时,编译器读取/写入实际变量,而不是一些“临时变量”复制”。
但是,volatile
不保证:
数据是自动更新的 - 换句话说,如果你存储一些东西,可能会存储一半新数据,而另一半是旧值,导致各种“有趣”的结果[例如随机float
] 中的值。
其他 cpu 的缓存知道该值已更改 - 换句话说,一个 CPU 读取的值可能已在一段时间前在另一个 CPU 上更新 - 例如 b
上面的代码 - 尽管 volatile
,CPU 很可能没有导致刷新另一个 CPU 的缓存。
您需要注意缓存和原子更新,以确保您不会遇到因其中任何一个未正确完成而导致的“有趣”错误。这当然适用,无论您是否使用全局变量或以其他方式在处理器之间共享数据——唯一可以依赖它的情况是当您通过操作系统或运行时环境拥有适当的接口(interface)时,它为这些事情提供了保证。