运行 4 和 8 线程的同等时间执行
Equal time execution for running with 4 and 8 threads
我使用 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
您有 4 个物理核心。 promise of hyperthreading 是每个核心可以 "think about" 两个任务,并且当它在一个任务上被阻塞时会在两个任务之间动态切换(例如,如果它需要等待内存操作完成)。从理论上讲,这意味着等待某些操作完成所浪费的时间减少了。然而,在实践中,实际的性能提升往往远不及将内核数量加倍所获得的 2 倍提升。改进通常在 0 到 0.3 倍之间,有时甚至会导致速度下降。
4 个线程本质上是您正在使用的计算机的有用线程上限。具有 8 个物理内核的计算机可能会获得您期望的加速。
我使用 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
您有 4 个物理核心。 promise of hyperthreading 是每个核心可以 "think about" 两个任务,并且当它在一个任务上被阻塞时会在两个任务之间动态切换(例如,如果它需要等待内存操作完成)。从理论上讲,这意味着等待某些操作完成所浪费的时间减少了。然而,在实践中,实际的性能提升往往远不及将内核数量加倍所获得的 2 倍提升。改进通常在 0 到 0.3 倍之间,有时甚至会导致速度下降。
4 个线程本质上是您正在使用的计算机的有用线程上限。具有 8 个物理内核的计算机可能会获得您期望的加速。