Delphi 有与 C 的 volatile 变量等效的东西吗?

发布于 2024-07-07 10:16:16 字数 256 浏览 6 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

趁年轻赶紧闹 2024-07-14 10:16:16

简短的回答:不。

但是,如果您遵循以下方法,我不知道编译器的保守方法会改变读取或写入的次数:

当读取跨线程可见位置时,在执行任何进一步操作之前将其值保存到本地操纵; 类似地,将写入限制为单个分配。

当表达式之间存在对非内联方法的调用时,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.

像极了他 2024-07-14 10:16:16

根据 在 Delphi 移动开发语言白皮书中,Delphi 的移动编译器支持 [易失性] 属性自首次引入以来:

易失性属性用于标记可能被不同线程更改的字段,以便代码生成不会优化在寄存器或其他临时内存位置中复制值的操作。

您可以使用易失性属性来标记以下声明:

  • 变量(全局变量和局部变量)
  • 参数
  • 记录或类的字段。

不能使用 volatile 属性来标记以下声明:

  • 类型
  • 过程、函数或方法
  • 表达式

<前><代码>类型
TMyClass = 类
私人的
[易失性] FMyVariable: TMyType;
结尾;

从 Delphi 10.1 Berlin 开始,桌面编译器现在也支持 [易失性]

所有编译器支持的属性

现在,所有 Delphi 编译器都支持以下属性:

According to The Delphi Language for Mobile Development whitepaper, Delphi's mobile compilers have supported a [volatile] attribute since they were first introduced:

The volatile attribute is used to mark fields that are subject to change by different threads, so that code generation does not optimize copying the value in a register or another temporary memory location.

You can use the volatile attribute to mark the following declarations:

  • Variables (global and local)
  • Parameters
  • Fields of a record or a class.

You cannot use the volatile attribute to mark the following declarations:

  • Type
  • Procedures, Functions or Methods
  • Expressions
type
  TMyClass = class
  private
    [volatile] FMyVariable: TMyType;
  end;

Starting with Delphi 10.1 Berlin, the desktop compilers now support [volatile] as well.

Attributes Supported by All Compilers

Now, all Delphi compilers support the following attributes:

末蓝 2024-07-14 10:16:16

我不知道有任何等效的指令,我也不认为 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.

っ左 2024-07-14 10:16:16

Delphi for .Net 也没有关键字,但 .Net 平台有它的 util 函数。 请参阅 Thread.VolatileReadThread.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.

壹場煙雨 2024-07-14 10:16:16

使用动态分配的指针?

var
  MyVarPtr: ^integer;
begin
  New(MyVarPtr);
  MyVarPtr^ := 5;
...

这应该可以防止编译器使用寄存器来存储整数值(但它可能仍然使用一个寄存器作为地址)。 不过,我不确定这与易失性相比如何。

Use dynamically allocated pointers?

var
  MyVarPtr: ^integer;
begin
  New(MyVarPtr);
  MyVarPtr^ := 5;
...

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文