时间切片的问题

时间:2012-09-01 17:20:19

标签: c multithreading pthreads

我试图看到时间切片的效果。它如何消耗大量的时间。实际上,我试图将某项工作划分为多个线程并查看效果。

我有两个核心处理器。所以两个线程可以并行运行。我试图看看我是否有一个由两个线程完成的工作,如果我有相同的工作由t线程完成,每个线程都在完成工作。时间切片在其中发挥了多少作用

由于时间切片是一个耗时的过程,我期待当我使用双线程进程或通过线程进程完成相同的工作时,t线程进程所花费的时间将更多

然而,我发现事实并非如此。我尝试了t = 10。而且它仍然比2线程进程更快。例如。如果我必须进行10,000,000次迭代,使用两个线程进程,我将有2个线程进行5,000,000次迭代,这样我们总共有 10,000,000次迭代。如果我必须处理10个线程进程,我将让每个线程进行1,000,000次迭代,这样我们总共有10,000,000个。

我期待10个线程进程消耗更多时间。但事实并非如此。代码中是否有任何错误?它对我来说很好

有什么建议吗?

4 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

对于一个应用程序来演示一个重要的,容易测量的减速,其中包含比处理器更多的线程,你必须在它上面工作:

1)线程必须是CPU密集型的,即。不会阻塞I / O或彼此。如果你使用一个简单的计数循环(听起来像你),那么是的,已经完成了。

2)您必须安排每个线程处理足够大的数据,以便L1缓存在上下文交换时需要大量刷新。如果只增加一个整数,则不会发生这种刷新,并且上下文切换开销太小(与计时器驱动的调度运行之间的间隔相比),以便轻松演示。

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

答案 2 :(得分:0)

您的计算机上有多少CPU核心?关于CPU绑定线程的事情是,即使可能存在设置和调度当您只有一个线程时不存在的线程的开销,如果这些线程实际上可以同时执行(而不是仅仅出现在在同一时间执行)然后线程仍然可以产生大于开销成本的增益。

答案 3 :(得分:0)

如果您有多个逻辑核心,您的线程将并行执行。

要测试您的假设,您需要将它们固定到单个逻辑核心。