Lim*_*ent 40 .net c# multithreading volatile
有人问过像我这样的问题,但我的情况有点不同.现在的问题是,"为什么volatile关键字不允许C#在类型System.Double和System.Int64等?"
乍一看,我回答了我的同事,"好吧,在32位机器上,这些类型至少需要两个滴答才能进入处理器,.Net框架的目的是抽象出像这样的处理器特定细节. " 他回答说:"如果由于处理器特定的问题导致你无法使用某个功能,那么它就不会抽象出任何东西!"
他暗示一个特定于处理器的细节不应该出现在使用框架的人身上,这个框架"抽象"远离程序员的细节.因此,框架(或C#)应该抽象出那些并做它需要做的事情来提供相同的保证System.Double等等(无论是信号量,内存障碍还是其他).我认为框架不应该增加信号量的开销volatile,因为程序员不期望使用这样的关键字这样的开销,因为32位类型不需要信号量.64位类型的更大开销可能会让人感到意外,因此,更好的.Net框架只是不允许它,并且如果开销是可接受的,那么就可以在更大的类型上使用自己的信号量.
这导致我们调查volatile关键字的全部内容.(见本页).该页面在说明中说明:
在C#中,在字段上使用volatile修饰符可确保对该字段的所有访问都使用VolatileRead或VolatileWrite.
嗯..... VolatileRead并且VolatileWrite都支持我们的64位类型!! 那么我的问题是,
"为什么volatile关键字不允许
C#在类型System.Double和System.Int64等?"
Eri*_*ert 17
他暗示一个特定于处理器的细节不应该出现在使用框架的人身上,这个框架"抽象"远离程序员的细节.
如果您使用低锁技术(如易失性字段,显式内存屏障等),那么您完全处于特定于处理器的详细信息中.为了编写使用低锁技术的正确,可移植,强大的程序,您需要在深层精确地理解处理器是什么,并且不允许执行重新排序,一致性等等.
这个特性的要点是说"我放弃了单线程编程所保证的方便抽象,并通过深入了解我的处理器实现知识来获得性能提升." 当您开始使用低锁技术而不是更多抽象时,您应该期待更少的抽象.
大概是因为某种原因,你会"走向金属"; 你支付的价格是必须处理所述金属的怪癖.
And*_*rey 12
是.原因是你甚至无法阅读double或long在一次操作中.我同意这是一个糟糕的抽象.我有一种感觉,理由是原子地阅读它们需要努力,而且对于编译器而言太聪明了.所以他们让你选择最好的解决方案:locking Interlocked,等等.
有趣的是,它们实际上可以使用MMX寄存器在32位上原子读取.这就是Java JIT编译器的功能.它们可以在64位机器上原子读取.所以我认为这是设计中的严重缺陷.
不是你的问题的答案,但......
我很确定你引用的MSDN文档在声明"在字段上使用volatile修饰符保证对该字段的所有访问都使用VolatileRead或VolatileWrite"时是不正确的.
直接读取或写入volatile字段只会产生半栅栏(读取时的获取栅栏和写入时的释放栅栏).
的VolatileRead和VolatileWrite方法使用MemoryBarrier在内部,其产生一个全栅栏.
Joe Duffy对并发编程知之甚少; 这是他对易变性的看法:
(顺便说一句,许多人想知道标记为volatile的变量的加载和存储之间的区别以及对Thread.VolatileRead和Thread.VolatileWrite的调用.区别在于前面的API实现比jitted代码更强:它们实现了获取/通过在右侧发出完整的栅栏来释放语义.调用API也更昂贵,但至少允许您根据呼叫站点来决定个别加载和存储需要MM保证.)
| 归档时间: |
|
| 查看次数: |
7986 次 |
| 最近记录: |