优化大数组和(多线程)

时间:2018-11-13 20:02:43

标签: c++ multithreading

因此,我想优化一个非常大的数组的总和,为此,我编写了一个多线程代码。问题在于,使用此代码,我仅使用一个线程而不是2个或3个或4个线程就可以获得更好的计时结果。

有人可以向我解释为什么会这样吗? (此外,本学期我仅开始使用C ++进行编码,直到那时我才知道C,所以对可能出现的愚蠢错误感到抱歉)

这是线程代码

    *localSum = 0.0;
    for (size_t i = 0; i < stop; i++)
            *localSum += v[i];

主要过程代码

    int numThreads = atoi(argv[1]);
    int N = 100000000;

    // create the input vector v and put some values in v
    vector<double> v(N);
    for (int i = 0; i < N; i++)
            v[i] = i;

    // this vector will contain the partial sum for each thread
    vector<double> localSum(numThreads, 0);

    // create threads. Each thread will compute part of the sum and store
    // its result in localSum[threadID] (threadID = 0, 1, ... numThread-1)
    startChrono();
    vector<thread> myThreads(numThreads);

    for (int i = 0; i < numThreads; i++){
            int start = i * v.size() / numThreads;
            myThreads[i] = thread(threadsum, i, numThreads, &v[start], &localSum[i],v.size()/numThreads);
    }


    for_each(myThreads.begin(), myThreads.end(), mem_fn(&thread::join));

    // calculate global sum
    double globalSum = 0.0;
    for (int i = 0; i < numThreads; i++)
            globalSum += localSum[i];

    cout.precision(12);
    cout << "Sum = " << globalSum << endl;
    cout << "Runtime: " << stopChrono() << endl;

    exit(EXIT_SUCCESS);
}

1 个答案:

答案 0 :(得分:1)

有几件事:

1-数组不够大。矢量化流媒体添加真的很难被击败。您需要比添加功能更复杂的功能才能真正看到结果。或非常大的阵列。

2-与此相关,所有线程创建和连接的开销将淹没线程带来的任何性能提升。添加确实非常快,并且您可以轻松地使CPU的功能单元饱和。为了使该线程甚至不能在同一内核上成为超线程,它必须完全在另一个内核上(因为超线程都将争夺浮点单元)。

要对此进行测试,您可以尝试在启动计时器之前创建所有胎面,并在停止计时器之后将其全部停止(让它们设置完成标志而不是等待联接)。

3-您的所有localsum变量都共享同一缓存行。最好是将localsum变量放在堆栈上,然后将结果放入数组中,而不是直接添加到数组中:https://mechanical-sympathy.blogspot.com/2011/07/false-sharing.html

如果由于某种原因,您需要使该数组中的其他对象可观察到总和,请像这样填充localsum向量条目,以使它们不会共享同一缓存行:

struct localsumentry {
  double sum;
  char pad[56];
};