Delphi 有与 C 的 volatile 变量等效的东西吗?
在 C 和 C++ 中,变量可以标记为 易失性,这意味着编译器不会优化它,因为它可能在声明对象的外部被修改。 Delphi 编程中有等效的吗? 如果不是关键字,也许有解决方法?
我的想法是使用Absolute,但我不确定,这可能会带来其他副作用。
In C and C++ a variable can be marked as volatile, which means the compiler will not optimize it because it may be modified external to the declaring object. Is there an equivalent in Delphi programming? If not a keyword, maybe a work around?
My thought was to use Absolute, but I wasn't sure, and that may introduce other side effects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
简短的回答:不。
但是,如果您遵循以下方法,我不知道编译器的保守方法会改变读取或写入的次数:
当读取跨线程可见位置时,在执行任何进一步操作之前将其值保存到本地操纵; 类似地,将写入限制为单个分配。
当表达式之间存在对非内联方法的调用时,Delphi 编译器不会对非局部位置表达式执行公共子表达式消除 (CSE),因为编译器不会进行过程间优化,因此即使对于单个位置表达式,它也不会正确。 - 线程代码。
因此,您可能需要使用 InterlockedExchange() 进行读取和写入来强制执行此操作; 此外,这将导致完整的内存屏障,因此处理器也不会重新排序读取和写入。
Short answer: no.
However, I am not aware of any situation in which the conservative approach of the compiler will change the number of reads or writes if you follow this approach:
When reading a cross-thread visible location, save its value to a local before doing any further manipulation; similarly, restrict writes to a single assignment.
The Delphi compiler does not perform common subexpression elimination (CSE) on non-local location expressions when there are calls to non-inlined methods between the expressions, as the compiler doesn't do interprocedural optimization and thus it would not be correct even for single-threaded code.
So, you may want to use InterlockedExchange() to do your reads and writes to force this; additionally, this will cause a full memory barrier, so the processor won't reorder reads and writes either.
根据 在 Delphi 移动开发语言白皮书中,Delphi 的移动编译器支持
[易失性]
属性自首次引入以来:从 Delphi 10.1 Berlin 开始,桌面编译器现在也支持
[易失性]
。所有编译器支持的属性
According to The Delphi Language for Mobile Development whitepaper, Delphi's mobile compilers have supported a
[volatile]
attribute since they were first introduced:Starting with Delphi 10.1 Berlin, the desktop compilers now support
[volatile]
as well.Attributes Supported by All Compilers
我不知道有任何等效的指令,我也不认为 absolute 指令会对您有帮助。 absolute 允许您有两个使用相同地址的变量,但我认为这不会阻止编译器优化对该内存的引用。
我想你可以使用指针并自己管理它。 这样,无论编译器在优化指针值的检索方面做什么,它都不应该假设存储在该地址的值与上次读取它时的值相同,但这纯粹是猜测。
I don't know of any equivalent, nor do I think that the absolute directive will help you. absolute allows you to have two variables that use the same address, but I do not think it will prevent the compiler from optimising references to that memory.
I imagine you could use a pointer and manage it yourself. That way whatever the compiler does as far as optimising retrival of the pointer value, it should not assume the value stored at the address is the same as last time it read it, but this is pure speculation.
Delphi for .Net 也没有关键字,但 .Net 平台有它的 util 函数。 请参阅 Thread.VolatileRead 和 Thread.VolatileWrite。
Delphi for .Net does not have the keyword either, but the .Net platform has util functions for it. See Thread.VolatileRead and Thread.VolatileWrite.
使用动态分配的指针?
这应该可以防止编译器使用寄存器来存储整数值(但它可能仍然使用一个寄存器作为地址)。 不过,我不确定这与易失性相比如何。
Use dynamically allocated pointers?
This should keep the compiler from using a register for the integer value (but it might still use one for the address). I am not sure how that compares to volatile, though.