Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 正在寻找线程同步性能问题的解释_C_Multithreading_Performance_Synchronization_Windows Server 2008 - Fatal编程技术网

C 正在寻找线程同步性能问题的解释

C 正在寻找线程同步性能问题的解释,c,multithreading,performance,synchronization,windows-server-2008,C,Multithreading,Performance,Synchronization,Windows Server 2008,当使用内核对象来同步运行在不同CPU上的线程时,使用Windows Server 2008 R2相对于其他操作系统是否会有额外的运行时成本 编辑:从答案中可以看出,这个问题还应该包括“当以较低的CPU利用率水平运行时”这句话。我在自己对这个问题的回答中包含了更多信息 背景 我开发的产品使用共享内存和信号量在进程之间进行通信(当两个进程在同一台机器上运行时)。有关Windows Server 2008 R2性能问题的报告(在此之后我将其缩短为Win2008R2)使我发现,与其他操作系统相比,Win

当使用内核对象来同步运行在不同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 );
  }
测试中的两个线程都运行了一百万次迭代。这些测试都在相同的机器上运行。Win Server 2008和Server 2003编号来自双引导计算机。Win 7机器具有完全相同的规格,但是不同的物理机器。本例中的机器为联想T420笔记本电脑,核心为i5-2520M 2.5GHz。显然不是服务器类机器,但我在真正的服务器类硬件上得到了类似的结果。括号中的数字是第一列与给定列的比率

有没有解释为什么这一个操作系统似乎会为跨CPU的内核级同步带来额外的费用?或者您是否知道可能会影响这一点的一些配置/调优参数

虽然这会使这篇文章变得非常冗长和冗长,但如果有人想要的话,我可以发布上面这些数字来自的测试代码的增强版本。这将显示循环逻辑的实施和测试的自旋锁版本

扩展背景 试着回答一些不可避免的问题,关于为什么事情是这样做的。我也一样。。。当我读到一篇帖子时,我常常想知道为什么我会问。以下是一些澄清的尝试:

  • 什么是应用程序?它是一个数据库服务器。在某些情况下,客户在与服务器相同的机器上运行客户机应用程序。在这种情况下,使用共享内存进行通信(与套接字相比)会更快。这个问题与共享内存通信有关
  • 工作负载真的那么依赖于事件吗?好。。。共享内存通信是使用命名信号量实现的。客户机发出信号量,服务器读取数据,服务器在响应就绪时向客户机发出信号量。在其他平台上,它的速度非常快。在Win2008R2上,它不是。它还非常依赖于客户应用程序。如果他们编写时向服务器发出大量的小请求,那么这两个进程之间就会有大量的通信
  • 可以使用轻型锁吗?可能地我已经在看了。但它独立于原始问题

    • 很可能是操作系统安装配置不同。可能慢系统被配置为不允许多个线程同时调度进程。如果其他一些高优先级进程总是(或大部分)准备好运行,那么唯一的选择就是让线程按顺序运行,而不是并行运行。

      这不是一个合理的基准测试,您的信号量总是在同一进程中被冻结(因此可能在同一CPU/核心上)。在现实世界中,锁定成本的一个重要部分是当不同的CPU/内核争夺对内存区域的独占访问(在缓存之间来回反弹)时所涉及的内存访问。寻找一些更真实的基准测试(抱歉,不是我的领域),用(人为的,但真实的)测试数据(更好的)度量(应用程序的一些简化版本)


      [基准测试的测试数据永远不应该是用于测试或回归测试的数据:后面提到的(可能很少使用)极端情况,你需要“典型”的基准测试运行。]

      从评论中得出一个答案:

      可能服务器未设置为高性能电源计划?Win2k8可能具有不同的默认值。默认情况下,许多服务器都不是这样,这会严重影响性能

      OP确认这是根本原因


      这是导致这种行为的一个有趣原因。当我做一些完全不同的事情时,这个想法闪现在我的脑海中。

      我在这里添加了这个额外的“答案”信息,而不是将其隐藏在我过长的作品中。@usr为我指出了电源管理选项建议的正确方向。OP中的人为测试以及原始问题都涉及不同线程之间的大量握手。在现实世界的应用程序中,握手是跨不同的进程进行的,但测试表明,如果是线程或进程进行握手,结果不会有所不同。在Windows Server 2008 R2中,在CPU使用率较低(例如,5%到10%)的情况下运行时,电源设置似乎会极大地影响信号量(内核同步对象)在CPU之间的共享。我对这一点的理解完全基于测量和计时应用

      A也谈到了这一点

      测试设置 操作系统电源选项设置Windows Server 2008 R2的默认电源计划为“平衡”。将其更改为“高性能”选项对该测试的性能有很大帮助。特别是,“更改高级电源设置”下的一个指定设置似乎是关键设置。“高级设置”在“处理器电源管理”下有一个称为“最小处理器状态”的选项。平衡计划下的默认值似乎为5%。在我的测试中将其更改为100%是关键

      B
      #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;
      }
      
      +----------------+-----------+---------------+----------------+
      |       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)   |
      +----------------+-----------+---------------+----------------+
      
      ╔════════════════╦═════════════╦═══════════════╦════════════╗
      ║                ║ (i)Balanced ║ (ii) HighPerf ║ (iii) BIOS ║
      ╠════════════════╬═════════════╬═══════════════╬════════════╣
      ║ (a) Simple     ║ 21.4 s      ║ 9.2 s         ║ 4.0 s      ║
      ║ (b) Real World ║ 9.3 s       ║ 2.2 s         ║ 1.7 s      ║
      ╚════════════════╩═════════════╩═══════════════╩════════════╝