C++0x 和静态局部变量的性能损失?

Posted

技术标签:

【中文标题】C++0x 和静态局部变量的性能损失?【英文标题】:Performance loss in C++0x and static local variables? 【发布时间】:2011-05-15 16:05:25 【问题描述】:

什么是现实的性能损失,因为在 C++0x 中 所有其他线程都应该 在这种情况下等待

string& program_name() 
  static string instance = "Parallel Pi";
  return instance;

让我们假设最佳方案:程序员非常小心,即使有 100 个线程,只有 主线程 调用函数 program_name,所有其他 99 个工作线程忙于做有用的事情,不涉及调用这个“关键”函数。

我引用了新的 C++0x-Std § 6.7.(4) stmt.decl

...这样的对象在控件第一次通过其声明时被初始化...如果控件在初始化对象时同时进入声明,则并发执行应等待初始化完成...

实际编译器需要对我施加的实际开销是多少,以确保按照标准要求完成静态初始化。

是否需要锁/互斥锁?我认为它们很贵,即使不是真的需要? 如果它们很昂贵,是否会通过更便宜的机制来完成?

编辑:添加string...

【问题讨论】:

如果你使用单例,你就会遇到问题。这就是它的工作原理。 IIRC,在一个谷歌视频中,一位线程专家表示,由于采用了新算法,本地静态变量的初始化可以而且将会在严肃的 C++0x 实现中完成,而无需锁定线程安全的方式。 我猜你的意思是static string instance = ...; @Johannes:你能给我指点那个谷歌视频吗? 【参考方案1】:

如果在初始化对象时控件同时进入声明,则 并发执行应等待初始化完成...

我认为这在并发编程中是合理且非常正常的事情。无论如何,这个声明并没有说所有其他线程必须等待这个初始化。他们必须等待以防他们需要访问初始化对象。

是否需要锁/互斥锁?我认为它们很贵,即使不是真的需要?

可能是。 Mutex / lock 实际上并没有那么昂贵,只有当锁定的代码片段需要被许多甚至所有线程频繁访问时,它们才是昂贵的。

如果它们很昂贵,是否会通过更便宜的机制来完成?

还有另一种基于非锁定的解决方案 AFAIK。

【讨论】:

【参考方案2】:

如果您真的关心锁的价格,您可以简单地在启动工作线程之前调用该函数,这将初始化静态。如果您在线程启动后调用它,您或编译器都必须安排某种锁定,因此没有真正的额外开销。

【讨论】:

编译器是否不必为每个本地静态添加同步逻辑,以防它同时从两个线程中使用?即使编译器进行流分析,我也不指望它能够在大多数情况下证明任何事情,即使 main 的流直接导致了这一点而无需从其他编译单元调用任何函数,全局变量的初始化也可以启动线程。抱歉,我不明白你是如何避免为不需要的锁付费的。 @Ben 如果编译器做流分析,那么肯定可以看到只有一个执行线程。是否有人会这样做,我同意没有实际意义。但是,如果它不进行此类分析,something 最好在 MT 环境中锁定该静态。 @Neil:哦???让它悬而未决?不不不。这不得不处理。多线程现实世界。这将把战场留给那些其他语言。像 Java。或者更糟... ;-) @Neil:流分析必须了解自启动以来运行的每一段代码,而这在 C++ 编译模型下或在具有动态库的真实系统上是不可能的。标准中的线程很好,但默认情况下静态应该是不安全的(根据“你不为你不使用的东西付费”),并附带一个用于轻松便携式线程安全一次性初始化的库解决方案。跨度> 纯库实现不能解决线程的基本问题,我们需要某种保证先于什么发生。核心语言语义必须定义它。定义内存模型所需的语言。

以上是关于C++0x 和静态局部变量的性能损失?的主要内容,如果未能解决你的问题,请参考以下文章

lua脚本有静态局部变量吗

java中静态成员变量、实例变量、局部变量何时创建、何时销毁?

C语言局部变量全局变量,局部静态变量,全局静态变量,extern,static的区别

函数局部静态变量:从性能角度看的优缺点

C++11 静态局部变量和线程

全局变量局部变量静态全局变量静态局部变量在内存里的区别