是否存在互斥帮助摆脱易失性关键词? [英] does presence of mutex help getting rid of volatile key word ?

查看:116
本文介绍了是否存在互斥帮助摆脱易失性关键词?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多R / W锁类保持读,写和挂起的读,挂起的写计数器。互斥量保护它们从多个线程。

I have a multi-R/W lock class that keeps the read, write and pending read , pending write counters. A mutex guards them from multiple threads.

我的问题是,我们仍然需要将计数器声明为volatile,这样编译器不会在优化时搞错。

My question is Do we still need the counters to be declared as volatile so that the compiler won't screw it up while doing the optimization.

或者编译器考虑到计数器由互斥体保护。

Or does the compiler takes into account that the counters are guarded by the mutex.

我理解mutex是一个用于同步的运行时机制,而volatile关键字是一个编译时指示,使编译器在做优化时做正确的事。

I understand that the mutex is a run time mechanism to for synchronization and "volatile" keyword is a compile time indication to the compiler to do the right thing while doing the optimizations.

尊敬的,
-Jay。

Regards, -Jay.

推荐答案


  • volatile

  • 线程,锁定,内存障碍等。

volatile用于告诉编译器产生读取变量的代码内存,而不是寄存器。并且不重新排序代码。一般来说,不是优化或采取快捷方式。由Herb Sutter在另一个答案中引用的内存屏障(由互斥锁,锁等提供)。

volatile is used to tell the compiler to produce code to read the variable from memory, not from a register. And to not reorder the code around. In general, not to optimize or take 'short-cuts'.

用于防止 CPU 重新排序读/写存储器请求,而不管编译器如何做。

memory barriers (supplied by mutexes, locks, etc), as quoted from Herb Sutter in another answer, are for preventing the CPU from reordering read/write memory requests, regardless of how the compiler said to do it. ie don't optimize, don't take short cuts - at the CPU level.

类似,但实际上是非常不同的东西。

Similar, but in fact very different things.

在你的情况下,在大多数锁定情况下,volatile不是必需的,是因为为了锁定而进行的函数调用。即:

In your case, and in most cases of locking, the reason that volatile is NOT necessary, is because of function calls being made for the sake of locking. ie:

external void library_func(); // from some external library

global int x;

int f()
{
   x = 2;
   library_func();
   return x; // x is reloaded because it may have changed
}

,除非编译器可以检查library_func ()并确定它不会碰到x,它会重新读取x上的返回值。这是即使没有波动。

unless the compiler can examine library_func() and determine that it doesn't touch x, it will re-read x on the return. This is even WITHOUT volatile.

int f(SomeObject & obj)
{
   int temp1;
   int temp2;
   int temp3;

   int temp1 = obj.x;

   lock(obj.mutex); // really should use RAII
      temp2 = obj.x;
      temp3 = obj.x;
   unlock(obj.mutex);

   return temp;
}



在读取temp1的obj.x之后,编译器将重新读取obj.x for temp2 - 不是因为魔法的锁 - 而是因为它不确定是否lock()修改obj。你可以设置编译器标志,积极优化(无别名等),从而不重新读取x,但是一堆你的代码可能会开始失败。

After reading obj.x for temp1, the compiler is going to re-read obj.x for temp2 - NOT because of the magic of locks - but because it is unsure whether lock() modified obj. You could probably set compiler flags to aggressively optimize (no-alias, etc) and thus not re-read x, but then a bunch of your code would probably start failing.

对于temp3,编译器(希望)不会重新读取obj.x.
如果由于某种原因obj.x可以在temp2和temp3之间改变,那么你将使用volatile(和你的锁定将被破坏/无用)。

For temp3, the compiler (hopefully) won't re-read obj.x. If for some reason obj.x could change between temp2 and temp3, then you would use volatile (and your locking would be broken/useless).

,如果你的lock()/ unlock()函数以某种方式内联,也许编译器可以评估代码,看到obj.x不会改变。但是我保证在这里两个事情之一:
- 内联代码最终调用一些操作系统级锁定功能(从而防止评估)或
- 你调用一些asm内存屏障指令(即包装在内联函数像__InterlockedCompareExchange),你的编译器将识别,从而避免重新排序。

Lastly, if your lock()/unlock() functions were somehow inlined, maybe the compiler could evaluate the code and see that obj.x doesn't get changed. But I guarantee one of two things here: - the inline code eventually calls some OS level lock function (thus preventing evaluation) or - you call some asm memory barrier instructions (ie that are wrapped in inline functions like __InterlockedCompareExchange) that your compiler will recognize and thus avoid reordering.

编辑:PS我忘了提一下 - 对于pthreads的东西,一些编译器被标记为POSIX兼容,这意味着,除其他外,他们将识别pthread_函数,不做坏的优化周围。即使C ++标准没有提及线程,这些编译器也会(至少最低限度)。

P.S. I forgot to mention - for pthreads stuff, some compilers are marked as "POSIX compliant" which means, among other things, that they will recognize the pthread_ functions and not do bad optimizations around them. ie even though the C++ standard doesn't mention threads yet, those compilers do (at least minimally).

您不需要挥发性。

这篇关于是否存在互斥帮助摆脱易失性关键词?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆