5

タイムスライスの効果を見ようとしていました。そして、それがどのようにかなりの時間を消費する可能性があるか。実は、ある作業をスレッド数に分割して効果を見ようとしていたのです。

2 コア プロセッサを使用しています。したがって、2 つのスレッドを並行して実行できます。私は、2 つのスレッドによって実行される作業があるかどうか、および各スレッドが作業の w/t を実行する t スレッドによって同じ作業が行われるかどうかを確認しようとしていました。タイムスライシングはその中でどのくらいの役割を果たしますか

タイムスライシングは時間のかかるプロセスであるため、2 スレッド プロセスまたは at スレッド プロセスを使用して同じ作業を行う場合、t スレッド プロセスにかかる時間はより長くなると予想していました。

しかし、そうではないことがわかりました。t=10 にしてみました。それでも2スレッドプロセスよりも高速です。たとえば。10,000,000 回の反復を実行する必要がある場合、2 つのスレッド プロセスで 2 つのスレッドに 5,000,000 回の反復を実行させ、合計 10,000,000 回の反復を行います。10 スレッドのプロセスを処理する必要がある場合は、各スレッドに 1,000,000 の反復を実行させて、合計も 10,000,000 になるようにします。

10 スレッドのプロセスがより多くの時間を消費すると予想していました。しかし、そうではありません。コードにバグはありますか?それは私にはうまく見えます

助言がありますか?

4

4 に答える 4

1

並列バージョンでは、10000000 (1000 万) x 1000 回の反復と、スレッドごとに 5000000 (500 万) x 1000 回の反復を実行しています。私の経験では、起動時のオーバーヘッドを無視できるものにするのに十分な作業です。結果は私には正しいようです。

2 つのコアと 2 つのスレッドの場合、(少なくとも 2 つのワーカー スレッド間で) タイムスライスは関係ありません。スケジューラは、スレッドを別々のコアに配置してそこに保持するのに十分なほどスマートだからです。

いくらかの劣化を確認するには、キャッシュを介してメモリを移動する必要があります。これにより、各コンテキスト スイッチがキャッシュから一部のデータを削除することで実際にパフォーマンスが低下するようになります。これが私が得ている実行時間です:

./a.out 2 500000000
スレッド数 = 2
各スレッドの反復回数 = 250000000
合計所要時間 = 5.931148

./a.out 1000 500000000
スレッド数 = 1000
各スレッドの反復回数 = 500000
合計所要時間 = 6.563666

./a.out 2000 500000000
スレッド数 = 2000
各スレッドの反復回数 = 250000
総所要時間 = 7.087449

そして、これがコードです。私は基本的に、指定されたスレッド間で大きな配列を分割し、配列内のすべての項目を二乗しています:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

long* array;
int length;
int threads;

void *tfunc(void *arg) {
  int n = (int)arg;
  int i;
  int j;
  int x;
  long sum = 0;
  //printf("%d\n",*n);
  int start = n * (length / threads);
  int end = (n + 1) * (length / threads);

  for (i=start; i<end; i++) {
    array[i] = array[i] * array[i];
    //printf("%d\n",i);
  }
  return(0);

}

double timestamp() {
  struct timeval tp;
  gettimeofday(&tp, NULL);
  return (double)tp.tv_sec + tp.tv_usec / 1000000.;
}

int main(int argc, char *argv[]) {
  int numberOfIterations = atoi(argv[2]);
  int numberOfThreads = atoi(argv[1]);
  int i;
  printf("Number of threads = %d\n",numberOfThreads);
  printf("Number of iterations in each thread = %d \n", numberOfIterations / numberOfThreads);
  pthread_t workerThreads[numberOfThreads];
  int *arg = &numberOfIterations;

  array = (long*)malloc(numberOfIterations * sizeof(long));
  length = numberOfIterations;
  threads = numberOfThreads;
  int result[numberOfThreads];

  double timeTaken;
  timeTaken = timestamp();

  for(i=0; i<numberOfThreads; i++) {
    result[i] = pthread_create(workerThreads+i, NULL, tfunc, (void*)i);
  }

  for(i=0; i<numberOfThreads; i++) {
    pthread_join(workerThreads[i], NULL);
  }

  timeTaken = timestamp() - timeTaken;
  printf("Total time taken = %f\n", timeTaken);
  /*printf("The results are\n");
  for(i=0; i<numberOfThreads; i++) {
    printf("%d\n",result[i]);
  }*/

  free(array);
  exit(0);
}
于 2012-09-01T20:00:58.980 に答える
1

プロセッサよりもはるかに多くのスレッドを使用してアプリが大幅に、簡単に測定可能な速度低下を示すようにするには、次の作業を行う必要があります。

1) スレッドは CPU を集中的に使用する必要があります。I/O または相互にブロックしません。単純なカウント ループを使用している場合 (そのように聞こえます)、はい、完了です。

2) コンテキスト スワップ時に L1 キャッシュが大量のフラッシュを必要とするように、十分な大きさのデータを処理するように各スレッドを配置する必要があります。1 つの整数をインクリメントするだけでは、このフラッシュは発生せず、コンテキスト スイッチのオーバーヘッドは小さすぎて (タイマー駆動のスケジューリング実行間の間隔と比較して)、簡単に実証できません。

Windows サンプル データ、最小限のキャッシュ フラッシュ、i7、4/8 コア:

8 tests,
400 tasks,
counting to 10000000,
using 8 threads:
Ticks: 2199
Ticks: 2184
Ticks: 2215
Ticks: 2153
Ticks: 2200
Ticks: 2215
Ticks: 2200
Ticks: 2230
Average: 2199 ms

8 tests,
400 tasks,
counting to 10000000,
using 32 threads:
Ticks: 2137
Ticks: 2121
Ticks: 2153
Ticks: 2138
Ticks: 2137
Ticks: 2121
Ticks: 2153
Ticks: 2137
Average: 2137 ms

8 tests,
400 tasks,
counting to 10000000,
using 128 threads:
Ticks: 2168
Ticks: 2106
Ticks: 2184
Ticks: 2106
Ticks: 2137
Ticks: 2122
Ticks: 2106
Ticks: 2137
Average: 2133 ms

8 tests,
400 tasks,
counting to 10000000,
using 400 threads:
Ticks: 2137
Ticks: 2153
Ticks: 2059
Ticks: 2153
Ticks: 2168
Ticks: 2122
Ticks: 2168
Ticks: 2138
Average: 2137 ms
于 2012-09-02T09:22:49.527 に答える
0

マシンにはCPUコアがいくつありますか?CPUにバインドされたスレッドについてのことは、スレッドが1つしかない場合は存在しないスレッドをセットアップおよびスケジュールするためのオーバーヘッドがある場合でも、それらのスレッドが実際に同時に実行できる場合(同時に実行する)場合でも、スレッドはオーバーヘッドコストよりも大きなゲインを生成できます。

于 2012-09-01T17:36:43.770 に答える
0

複数の論理コアがある場合、スレッドは並行して実行されます。

仮説をテストするには、それらを単一の論理コアに固定する必要があります。

于 2012-09-01T17:44:19.937 に答える