代码之家  ›  专栏  ›  技术社区  ›  koshachok

使用4和8个线程运行时的等时间执行

  •  4
  • koshachok  · 技术社区  · 6 年前

    我使用OpenMP测试了一些代码。这是:

    #include <chrono>
    #include <iostream>
    #include <omp.h>
    
    #define NUM_THREADS 8
    #define ARR_SIZE 10000
    
    class A {
    private: 
        int a[ARR_SIZE];
    public:
        A() {
            for (int i = 0; i < ARR_SIZE; i++)
                a[i] = i;
        }
    // <<-----------MAIN CODE HERE--------------->
        void fn(A &o1, A &o2) {
            int some = 0;
            #pragma omp parallel num_threads(NUM_THREADS)
            {
                #pragma omp for reduction(+:some)
                for (int i = 0; i < ARR_SIZE; i++) {
                    for (int j = 0; j < ARR_SIZE; j++)
                        some += o1.a[i] * o2.a[j];
                }
            }
            std::cout << some <<std::endl;
        }
    };
    
    int main() {
        A a,b,c;
        auto start = std::chrono::high_resolution_clock::now();
        c.fn(a,b);
        auto end = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> elapsed = end - start;
        std::cout << elapsed.count();
    }
    

    执行时间:

    • 1螺纹:0.233663秒

    • 2螺纹:0.12449秒

    • 4螺纹:0.0665889秒

    • 8螺纹:0.0643735秒

      如您所见,4线程和8线程的执行几乎没有区别。这种行为的原因是什么?如果您在您的机器上尝试此代码,也会很好;)。

    P、 S.我的处理器:

    Model:               Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz 
    CPU(s):              8
    On-line CPU(s) list: 0-7
    Thread(s) per core:  2
    Core(s) per socket:  4
    Socket(s):           1
    
    1 回复  |  直到 4 年前
        1
  •  4
  •   zneak    6 年前

    您有4个物理核心。这个 promise of hyperthreading 每个核心都可以“思考”两个任务,当它在一个任务上被阻塞时(例如,如果它需要等待内存操作完成),会在这两个任务之间动态切换。理论上,这意味着等待某些操作完成所浪费的时间减少了。然而,在实践中,实际性能的提高往往远不及通过将内核数量增加一倍所获得的2倍的提高。改善通常在0到0.3倍之间,有时甚至会导致减速。

    4线程基本上是您所使用的计算机的有用线程上限。一台具有8个物理内核的计算机可能会得到您期望的加速。