串行代码比C中只使用一个线程慢得多?

串行代码比C中只使用一个线程慢得多?,c,multithreading,parallel-processing,C,Multithreading,Parallel Processing,因此,我用线程进行了一些基准测试,并编写了以下代码: 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[]和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;
  }
}
第二个是这样的:

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]);
请记住,我知道使用函数_th()调用多个线程不会使其并行化,这只是一个测试,因为我得到了非常奇怪的结果,所以我决定看看使用相同代码的一个线程和一个函数会发生什么

我在Intel Atom N270和windows XP中使用NUMPROC=1进行了测试

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

我在使用多处理器机器时也得到了类似的结果,甚至代码使用信号量来并行化线程所做的工作

有人知道会发生什么吗

编辑

颠倒顺序,每次运行多次,等等…->不变

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

使用QueryPerformanceCounter()->无更改

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


原始代码:

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

  • 在调用线程之前,请运行
    函数()
    两次甚至更频繁。 第二次调用函数将给出更快的结果
  • 在函数之前调用线程,结果将显示相反的结果。 该函数将显示更好的结果

  • 原因:所有的sqrt计算(或者至少很多)都可以在缓存中使用,不需要重新计算。这要快得多。

    可能您当前的线程(您在其中调用
    函数()
    )优先级较低?您是否在一个程序执行中按顺序运行了两个测试?我怀疑数据缓存对
    vetor[]
    access.1的影响。您是否尝试过颠倒顺序,先线程后函数?(缓存效应)2。你是怎么测量时间的?我试着倒计时,结果是一样的=/它可能是浮点运算的精确模式,例如
    sqrt
    。我听说Intel Atom的FPU性能很差。(主线程和新用户创建的线程对于C运行时数学库有不同的模式?)我尝试了反转另一个,两个线程都运行了多次,得到了相同的结果。好吧,我确实使用了你的代码,并且做得很好。结果非常清楚。再说一遍:你是如何测量时间的?你能报告一下“function()”和
    function_th()
    连续运行5次的时间吗?我实际上每个函数运行了5次,并得到了平均值。我测量的时间是“(双)时钟()/CLOCKS\u PER_second;”,然后从另一个中减去一个。
    clock()
    分辨率不好。在
    threaded()。按照
    threadlees()。只调用一个线程。将n增加到更高的值,以减少由于只执行一次操作而导致的错误。并用于计时目的。也许有机会将结果添加到上面的问题中(编辑)。使用QueryPerformanceCounter()->线程化更快。更高的n->->线程化速度更快。封闭整个线程创建不应该改变任何东西,因为它应该使“线程一”更慢,同样在我最初的基准测试中,我想计算线程创建开销。
    
    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]);