我正在开发一个库的多线程实现。在这个库的一个模块中,有一些全局变量(在程序执行中经常使用)。为了使对这些变量的访问更加安全,我使用线程本地存储(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)
变量是导致性能如此糟糕的原因吗?
发布于 2011-02-22 10:57:31
如果将它们声明为__declspec(thread)
,而它们以前是全局的,那么您已经更改了程序的含义以及它的性能特征。
当变量是全局变量时,每个线程都会引用一个副本。作为线程本地,每个单独的线程都有自己的变量,对该线程本地变量的更改仅在该线程中可见。
假设你真的想要线程局部变量,那么读写线程局部变量确实比普通变量更昂贵。每当你面对一个需要很长时间执行的操作时,最好的解决方案就是完全停止它。在这种情况下,有两种显而易见的方法:
在这些选项中,前者通常是首选的。选项2有一个很大的缺点,那就是如果函数调用另一个使用此变量的函数,就不能轻松地应用它。
选项1基本上相当于不使用全局变量(线程局部变量是全局变量的一种形式)。
当然,这一切都可能完全离谱,因为你对你的代码实际做的事情说得太少了。如果你想解决一个性能问题,你首先必须确定它在哪里,这意味着你需要测量。
发布于 2011-02-22 10:23:57
答案是:您需要分析应用程序,并测量花费时间最多的地方。如果它被证明是在经常引用TLS数据的函数中,那么“也许”可能是答案。
通常,即使是在自己编写的代码中,也很难找出性能不佳的原因:在两个简短段落中描述的程序中远程找出原因就更难了。
配置文件,然后优化。
https://stackoverflow.com/questions/5076853
复制