3

私はこのテストアプリケーションを作成しました。0から9999までの反復を経て、範囲内の整数ごとに、役に立たないが計算集約的な関数を計算します。その結果、プログラムは関数値の合計を出力します。複数のスレッドで実行するために、InterlockedIncrementを使用しています。増分後に反復回数が10000未満の場合、スレッドはこの反復を処理します。それ以外の場合は終了します。

なぜそれが私が望むほどスケーリングしていないのか疑問に思います。5スレッドの場合、1スレッドの場合は36秒であるのに対し、8秒で実行されます。これにより、最大4.5のスケーラビリティが得られます。OpenMPを使った実験中(わずかに異なる問題で)、スケーラビリティが大幅に向上しました。

ソースコードを以下に示します。

PhenomIIX6デスクトップでWindows7OSを実行しています。他にどのようなパラメータが関連しているのかわからない。

この最適ではないスケーラビリティについて説明していただけませんか。どうもありがとう。

#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スレッド): ここに画像の説明を入力してください

4

1 に答える 1

2

結果は、私のCPUがAMDTurboCoreテクノロジーをサポートしているという事実によって説明できることがわかりました。

Turbo COREモードでは、AMDPhenom™II X6 1090Tは、周波数速度を6コアの3.2GHzから3コアの3.6GHzにシフトします。

そのため、クロック周波数はシングルスレッドモードとマルチスレッドモードで同じではありませんでした。私はTurboCoreをサポートしていないCPUでマルチスレッドを使って遊んでいた。以下はの結果を示す画像です

  • AMD OverDriveユーティリティウィンドウ(TurboCoreのオン/オフを切り替えることができるもの)
  • TurboCoreをオンにして1スレッドで実行
  • TurboCoreをオフにして1スレッドで実行
  • 5スレッドで実行 ここに画像の説明を入力してください

助けようとした人々に感謝します。

于 2012-10-12T10:01:09.160 に答える