6

所以,我正在用线程做一些基准测试,我写了这些代码:

resp_threadless[] 和 resp_threaded[] 是全局 int 数组,它们的大小为 n;

int n = 100000;

void function() {
  for (long j = 0; j < n; ++j) {
    int count = 0;
    double x = vetor[j];
      while (x > 1.0) {
      x = sqrt(x);
      ++count;
    }
   resp_threadless[j] = count;
  }
}

DWORD WINAPI function_th( LPVOID lpParam ) {
for (long j = 0; j < n; ++j) {
    int count = 0;
    double x = vetor[j];
      while (x > 1.0) {
      x = sqrt(x);
      ++count;
    }
   resp_threadless[j] = count;
  }
}

我只打电话给她就对第一个函数进行了基准测试:

function();

第二个是这样的:

HANDLE hThreadArray[1];
DWORD dwThreads[1];
hThreadArray[0] = CreateThread(NULL, 0, function_th, NULL , 0, &(dwThreads[0]));
WaitForMultipleObjects(1, hThreadArray, TRUE, INFINITE);
CloseHandle(hThreadArray[0]);

请记住,我知道使用 function_th() 调用多个线程不会并行化它,这只是一个测试,因为我得到了非常奇怪的结果,所以我决定看看使用相同代码的一个线程和一个函数会发生什么.

我在 Intel Atom N270 和 NUMPROC = 1 的 windows XP 中对此进行了测试。

结果:序列号:1485 毫秒一个线程:425 毫秒

我使用多处理器机器得到了类似的结果,甚至使用信号量来并行化线程完成的工作的代码也是如此。

有谁知道会发生什么?

编辑

颠倒顺序,每次运行多次,等等... -> 没有变化

更高的 N -> 线程一按比例更快

使用 QueryPerformanceCounter() -> 没有变化

线程创建开销 -> 应该使线程更慢,而不是更快

原代码: http: //pastebin.com/tgmp5p1G

4

1 回答 1

2

这是一个cache hit问题。我怀疑您按照您在问题中描述的顺序进行了基准测试。首先调用函数,然后调用线程。当您更详细地对其进行基准测试时,您将观察到原因:数据(sqrt)在缓存中可用,因此代码将执行得更快。 测试证明:

  1. 在调用线程之前运行function()两次甚至更多次。第二次调用函数将给出更快的结果。
  2. 在函数之前调用线程,您的结果将显示相反的结果。该功能将显示更好的结果。

原因:所有 sqrt 计算(或至少其中很多)都在缓存中可用,不必重新计算。这要快得多。

于 2012-10-22T07:56:03.650 回答