【问题标题】:C - __declspec(thread) variables performancesC - __declspec(thread) 变量性能
【发布时间】:2011-07-01 21:39:18
【问题描述】:

我正在研究一个库的多线程实现。在这个库的一个模块中,有一些全局变量(在程序执行中经常使用)。为了使对这些变量的访问更加安全,我使用线程本地存储 (TLS) 关键字 __declspec(thread) 声明它们。

这是对库外部函数的调用。此函数使用带有全局变量的模块:

for(i = 0; i<n_cores; i++)
    hth[i] = (HANDLE)_beginthread((void(*)(void*))MT_Interface_DimenMultiCells,0,(void*)&inputSet[i]);

这样我猜库中使用的所有变量都会为每个线程复制。

当我在 x8 核处理器上运行程序时,完成操作所需的时间不会超过单进程实现所需时间的 1/3。

我知道不可能达到 1/8 的时间,但我认为至少 1/6 是可以达到的。

问题是:这些__declspec(thread) 变量是否是导致性能如此糟糕的原因?

【问题讨论】:

  • 你还在 StackOverflow 上吗?如果是这样,也许您可​​以让我们知道您的结论是什么:您是否测量了使用和不使用线程局部变量的性能?是这样,有什么不同?还是有其他方法解决了这个问题?

标签: c multithreading performance declspec


【解决方案1】:

答案是:您需要分析应用程序,并衡量花费最多时间的地方。如果它出现在经常引用 TLS 数据的函数中,那么“也许”可能就是答案。

即使在您自己编写的代码中,通常非常难以找出性能不佳的原因:在两个简短段落中描述的程序中远程执行此操作更加困难。

配置文件,然后优化。

【讨论】:

  • 感谢您的回答。 TLS 数据用于一组非常耗时的操作。但从你的话中,我明白这个事实不可能是原因。我会发布代码,但它太长了,这就是为什么我只是试图简要描述我的问题。
【解决方案2】:

如果您将它们声明为 __declspec(thread),之前它们是全局的,那么您已经改变了程序的含义以及它的性能特征。

当变量是全局变量时,每个线程都会引用一个副本。作为线程本地,每个单独的线程都有自己的变量,对该线程局部变量的更改仅在该线程中可见。

假设您真的想要线程本地,那么读取和写入线程本地变量确实比普通变量更昂贵。每当您面临需要很长时间才能执行的操作时,最好的解决方案就是完全停止执行该操作。在这种情况下,有两种明显的方法可以做到这一点:

  1. 将变量作为参数传递,使其驻留在堆栈中。访问堆栈变量很快。
  2. 如果您的函数经常读取和写入此变量,则在函数开始时将其复制(到局部变量中),处理该局部变量,然后在返回时将其写回线程本地。

在这些选项中,通常首选前者。选项 2 有一个很大的缺点,就是如果函数调用另一个使用该变量的函数,它就不能轻易应用。

选项 1 基本上相当于不使用全局变量(线程局部变量是全局变量的一种形式)。

当然,这一切都可能完全偏离了标准,因为您对您的代码实际执行的操作很少提及。如果您想解决性能问题,首先必须确定它在哪里,这意味着您需要进行衡量。

【讨论】:

  • 谢谢,我现在很确定问题出在线程本地变量访问时间上。我应该尝试实施解决方案“1”,然后再次测试性能。
猜你喜欢
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
相关资源
最近更新 更多