手动编写多线程循环 - 次优可伸缩性

时间:2012-10-11 11:43:47

标签: c++ multithreading boost-thread interlocked-increment

我已经编写了这个测试应用程序:它经历了从0到9999的迭代,对于该范围内的每个整数,它计算一些无用但计算密集的函数。结果,程序输出函数值的总和。为了让它在多个线程上运行我正在使用InterlockedIncrement - 如果在递增后迭代次数为< 10000,则线程处理此迭代,否则它将终止。

我想知道为什么它不像我希望的那样缩放。有5个线程,它运行8s而36s只有一个线程。这提供了~4.5的可伸缩性。在我使用OpenMP进行实验期间(略有不同的问题),我获得了更好的可扩展性。

源代码如下所示。

我在Phenom II X6桌面上运行Windows7操作系统。不知道其他参数可能相关。

您能帮我解释一下这种次优的可扩展性吗? 非常感谢。

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <vector>
#include <windows.h>
#include <iostream>
#include <cmath>

using namespace std;
using namespace boost;

struct sThreadData
{
  sThreadData() : iterCount(0), value( 0.0 ) {}
  unsigned iterCount;
  double value;
};

volatile LONG g_globalCounter;
const LONG g_maxIter = 10000;

void ThreadProc( shared_ptr<sThreadData> data )
{
  double threadValue = 0.0;
  unsigned threadCount = 0;

  while( true )
  {
    LONG iterIndex = InterlockedIncrement( &g_globalCounter );
    if( iterIndex >= g_maxIter )
      break;

    ++threadCount;

    double value = iterIndex * 0.12345777;
    for( unsigned i = 0; i < 100000; ++i )
      value = sqrt( value * log(1.0 + value) );

    threadValue += value;
  }

  data->value = threadValue;
  data->iterCount = threadCount;
}

int main()
{
  const unsigned threadCount = 1;

  vector< shared_ptr<sThreadData> > threadData;
  for( unsigned i = 0; i < threadCount; ++i )
    threadData.push_back( make_shared<sThreadData>() );

  g_globalCounter = 0;

  DWORD t1 = GetTickCount();
  vector< shared_ptr<thread> > threads;
  for( unsigned i = 0; i < threadCount; ++i )
    threads.push_back( make_shared<thread>( &ThreadProc, threadData[i] ) );

  double sum = 0.0;
  for( unsigned i = 0; i < threadData.size(); ++i )
  {
    threads[i]->join();
    sum += threadData[i]->value;
  }

  DWORD t2 = GetTickCount();
  cout << "T=" << static_cast<double>(t2 - t1) / 1000.0 << "s\n";

  cout << "Sum= " << sum << "\n";
  for( unsigned i = 0; i < threadData.size(); ++i )
    cout << threadData[i]->iterCount << "\n";

  return 0;
}

编辑: 附加此测试程序的示例输出(1和5个线程): enter image description here

1 个答案:

答案 0 :(得分:2)

事实证明,结果可以解释为我的CPU支持AMD Turbo Core技术。

  

在Turbo CORE模式下,AMD Phenom™II X6 1090T会改变频率   速度从六核上的3.2GHz到三核上的3.6GHz

因此在单线程模式和多线程模式下时钟频率不同。我习惯于在不支持TurboCore的CPU上进行多线程处理。以下是显示

结果的图像
  • AMD OverDrive实用程序窗口(允许打开/关闭TurboCore的东西)
  • 使用1个线程运行TurboCore ON
  • 使用1个线程运行TurboCore OFF
  • 5个线程的运行 enter image description here

非常感谢那些试图提供帮助的人。