C - __declspec(线程)变量表现

时间:2011-02-22 10:18:48

标签: c multithreading performance declspec

我正在研究库的多线程实现。在该库的一个模块中,存在一些全局变量(在程序执行中经常使用)。为了更安全地访问这些变量,我使用线程局部存储(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(线程)变量是如此糟糕表现的原因吗?

提前致谢,G.B。

2 个答案:

答案 0 :(得分:6)

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

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

假设你真的想要线程本地,那么读取和编写线程局部变量比普通变量更昂贵。每当您面对需要很长时间才能执行的操作时,最好的解决方案是完全停止执行操作。在这种情况下,有两种显而易见的方法:

  1. 将变量作为参数传递,以使其驻留在堆栈上。访问堆栈变量很快。
  2. 如果你有很多函数可以读取和写入这个变量,那么在函数的开头复制它(到一个局部变量),处理那个局部变量,然后在返回时,将它写回线程本地。
  3. 在这些选项中,前者通常是首选。选项2有一个很大的弱点,即如果函数调用另一个使用该变量的函数,它就不能轻易应用。

    选项1基本上等于不使用全局变量(线程本地是一种全局变量)。

    这当然可能是完全广泛的标记,因为你对你的代码实际做的事情说的很少。如果您想解决性能问题,首先必须确定它的位置,这意味着您需要进行测量。

答案 1 :(得分:5)

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

通常非常难即使在您自己编写的代码中也要找出性能不佳的原因:在两个简短段落中描述的程序远程执行它会更难。

配置文件,然后进行优化。