Mar*_*ins 9 c performance multithreading synchronization windows-server-2008
当使用内核对象来同步在不同CPU上运行的线程时,使用Windows Server 2008 R2相对于其他操作系统可能会有一些额外的运行时成本吗?
编辑:通过答案发现,问题还应该包括"在较低的CPU利用率水平下运行"这一短语.我在自己对这个问题的回答中包含了更多信息.
我研究的产品使用共享内存和信号量进行进程间的通信(当两个进程在同一台机器上运行时).有关Windows Server 2008 R2(我在此之后缩短为Win2008R2)的性能问题的报告使我发现在Win2008R2上的两个线程之间共享信号量与其他操作系统相比相对较慢.
我能够通过在两个线程上同时运行以下代码来重现它:
for ( i = 0; i < N; i++ )
{
WaitForSingleObject( globalSem, INFINITE );
ReleaseSemaphore( globalSem, 1, NULL );
}
Run Code Online (Sandbox Code Playgroud)
使用可以双启动到Windows Server 2003 R2 SP2和Windows Server 2008 R2的计算机进行测试,上面的代码片段在Win2003R2机器上运行速度比Win2008R2快7倍(Win2003R2为3秒,Win2008R2为21秒).
以下是上述测试的完整版本:
#include <windows.h>
#include <stdio.h>
#include <time.h>
HANDLE gSema4;
int gIterations = 1000000;
DWORD WINAPI testthread( LPVOID tn )
{
int count = gIterations;
while ( count-- )
{
WaitForSingleObject( gSema4, INFINITE );
ReleaseSemaphore( gSema4, 1, NULL );
}
return 0;
}
int main( int argc, char* argv[] )
{
DWORD threadId;
clock_t ct;
HANDLE threads[2];
gSema4 = CreateSemaphore( NULL, 1, 1, NULL );
ct = clock();
threads[0] = CreateThread( NULL, 0, testthread, NULL, 0, &threadId );
threads[1] = CreateThread( NULL, 0, testthread, NULL, 0, &threadId );
WaitForMultipleObjects( 2, threads, TRUE, INFINITE );
printf( "Total time = %d\n", clock() - ct );
CloseHandle( gSema4 );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我更新了测试以强制线程运行单个迭代并强制切换到每个循环的下一个线程.每个线程都表示下一个线程在每个循环结束时运行(循环式).我还更新了它,使用自旋锁作为信号量的替代品(这是一个内核对象).
我测试的所有机器都是64位机器.我把测试编译成32位.如果构建为64位,它整体运行速度更快一些,并将比率改变一些,但最终结果是相同的.除了Win2008R2之外,我还遇到了Windows 7 Enterprise SP 1,Windows Server 2003 R2 Standard SP 2,Windows Server 2008(不是R2)和Windows Server 2012 Standard.
以下是更新测试中的一些实际数字(时间以毫秒为单位):
+----------------+-----------+---------------+----------------+
| OS | 2 cpu sem | 1 cpu sem | 2 cpu spinlock |
+----------------+-----------+---------------+----------------+
| Windows 7 | 7115 ms | 1960 ms (3.6) | 504 ms (14.1) |
| Server 2008 R2 | 20640 ms | 2263 ms (9.1) | 866 ms (23.8) |
| Server 2003 | 3570 ms | 1766 ms (2.0) | 452 ms (7.9) |
+----------------+-----------+---------------+----------------+
Run Code Online (Sandbox Code Playgroud)
测试中的两个线程中的每一个都运行了100万次迭代.那些睾丸都在相同的机器上运行.Win Server 2008和Server 2003号码来自双引导计算机.Win 7机器具有完全相同的规格,但是是不同的物理机器.这款机器是配备Core i5-2520M 2.5GHz的联想T420笔记本电脑.显然不是服务器类机器,但我在真正的服务器类硬件上得到了类似的结果.括号中的数字是第一列与给定列的比率.
为什么这个操作系统似乎会为CPU内核级同步引入额外费用的任何解释?或者你知道一些可能影响这个的配置/调整参数吗?
虽然它会使这个非常冗长和长篇文章更长,我可以发布上述数字来自的测试代码的增强版本,如果有人想要的话.这将显示循环逻辑和测试的自旋锁版本的强制执行.
试图回答一些关于为什么以这种方式完成事情的不可避免的问题.我也是一样......当我读一篇文章时,我常常想知道为什么我甚至都在问.所以这里有一些尝试澄清:
从评论中提取答案:
也许服务器没有设置高性能电源计划?Win2k8 可能有不同的默认值。许多服务器默认情况下不是这样,这会严重影响性能。
OP 确认这是根本原因。
这是造成这种行为的一个有趣的原因。当我正在做一些完全不同的事情时,这个想法闪现在我的脑海中。
| 归档时间: |
|
| 查看次数: |
1427 次 |
| 最近记录: |