【问题标题】:Why different cpu pairs take different time to execute the same code为什么不同的 cpu 对需要不同的时间来执行相同的代码
【发布时间】:2019-10-03 14:56:15
【问题描述】:

我创建了一个程序,它从 argv 获取参数并为每个线程创建一个线程,线程关联设置为参数的 int 值。 例如 ./main 3 4 将创建两个线程,第一个将在第三个 cpu 上运行,第二个线程将使用第四个 cpu。

一个线程需要一秒钟才能完成(对数组 int[10000] 进行数学运算) 当我运行time ./main 1 2 时,我看到了预期的 1 秒实时 但是当我运行time ./main 1 3 时,我看到的是 2 秒而不是 1 我认为这与 numa 节点有关,但是 time ./main 1 4 导致 1 秒实时

经过更多测试,我发现只有 1 3 和 2 4 对花费的时间是预期的两倍。用户时间也增加了一倍。

$ time ./main 1 2
real    0m1.058s
user    0m2.100s

$ time ./main 1 3
real    0m2.019s
user    0m4.016s

$ time ./main 1 4
real    0m1.090s
user    0m2.152s

$ time ./main 2 4
real    0m2.014s
user    0m4.016s

$ time ./main 2 3
real    0m1.094s
user    0m2.156s

$ time ./main 3 4
real    0m1.170s
user    0m2.316s

我正在测试的代码。我跳过了set_affinity函数

void math_ops() {
  size_t len = 14800; // with this number it takes around 1s to compute on my hardware
  int* abc = new int[len+1];
  memset(abc, 7, len);
  for(int i = 1; i < len; i++) {
    for(int j = 1; j < len; j++) {
      abc[i] *= abc[j];
      abc[j+1] -= abc[i-1];
      abc[j-1] -= abc[i+1];
    }
  }
}

int main(int argc, char** argv) {
  std::vector<std::thread> vec(argc);
  int thread_num = argc - 1;
  for (int i = 0; i < thread_num; i++) {
    std::thread t(math_ops);
    // sets thread affinity equal to the second parameter
    set_affinity(t, atoi(argv[i+1]) - 1);
    vec[i] = std::move(t);
  }
  for (int i = 0; i < thread_num; i++) {
    vec[i].join();
  }
  return 0;
}

有谁知道为什么 cpu 对 1,3 和 2,4 的执行时间是原来的两倍?

【问题讨论】:

  • 不相关,但每当您想到new T[size] 时,您应该改用vector&lt;T&gt;。此外,以下memset() 调用看起来很可疑。
  • @UlrichEckhardt,谢谢,注意
  • @UlrichEckhardt 但这样做会使代码运行速度变慢两倍我已将int*memset 替换为std::vector&lt;int&gt; abc(len, 7); 我想我应该改用int abc[14800]
  • 好吧,一个在len字节上运行,另一个在len整数上运行。而且,只有一个会再次释放内存。
  • @UlrichEckhardt 对!谢谢

标签: c++ multithreading


【解决方案1】:

这可能是由于hyperthreading。 您看到的四个内核并不是真正的 4 个内核,它们可能只是两个内核,具有两倍的执行单元。这意味着在属于同一个物理内核的虚拟内核上运行的两个线程必须共享该内核的一些资源。

当您在两个不同的物理内核上运行时,不会共享资源,代码执行速度会更快。

您可以通过阅读/sys/devices/system/cpu/cpu0/topology/thread_siblings_list(将cpu0 替换为任何其他核心#)找出哪些核心是同级的

【讨论】:

  • 谢谢!我检查了,你是对的。第一个和第三个 cpu 在同一个核心上
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 2014-12-03
  • 1970-01-01
  • 2012-04-05
  • 2019-01-31
相关资源
最近更新 更多