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 和静态局部变量的性能损失?的主要内容,如果未能解决你的问题,请参考以下文章
java中静态成员变量、实例变量、局部变量何时创建、何时销毁?