gpt4 book ai didi

x86 - 不同的进程可以同时运行RDTSC吗?

转载 作者:行者123 更新时间:2023-12-03 18:43:51 25 4
gpt4 key购买 nike

不同的进程可以运行吗RDTSC同时?
或者这是一种只能同时运行一个内核的资源?
TSC在每个核心中(至少你可以为每个核心单独调整它),所以应该是可能的。但是超跑呢?

我该如何测试?

最佳答案

每个物理内核都有自己的 TSC;微代码不必脱离核心,因此它们没有竞争的共享资源。完全脱离核心会使它变慢,并使实现更加复杂。在每个内核内部都有一个物理计数器是一种更简单的实现,只需计算分配给所有内核的引用时钟信号的滴答数。

使用超线程,共享物理的逻辑内核总是竞争执行资源。来自 Agner Fog's instruction tables ,我们知道 Skylake 上的 RDTSC 前端是 20 uop,每 25 个周期有 1 个吞吐量。在每时钟不到 1 uop 而只执行 RDTSC 指令的情况下,争夺前端可能不是问题。

可能大部分 uops 可以在任何执行端口上运行,因此很可能两个逻辑线程都可以运行 rdtsc有了那个吞吐量。

但也许他们会竞争一个不完全流水线的执行单元。

您可以通过输入 times 20 rdtsc 来测试它在运行数百万次迭代的循环中,并在一个内核上单独运行该微基准测试,然后在固定到一个物理内核的逻辑内核上运行两次。

我很好奇,我自己在 Linux 上用 perf 做了这件事。在 Skylake i7-6700k 上,使用 taskset -c 3taskset -c 7 (Linux 枚举此 CPU 上的内核的方式,这些数字是第 4 个物理内核的逻辑内核。您可以检查/proc/cpuinfo 以了解您的系统。)

如果它们几乎同时完成,为了避免交错输出行,我使用了 bash 进程替换和 cat <(cmd1) <(cmd2)同时运行它们并以固定顺序打印输出。这些命令是taskset -c 3 perf stat -etask-clock:u,context-switches,cpu-migrations,page-faults,cycles:u,instructions:u,branches:u,branch-misses:u,uops_issued.any:u,uops_executed.thread:u,cpu_clk_thread_unhalted.one_thread_active:u -r2 ./testloop计算核心时钟周期(不是引用周期,所以我不必对涡轮/空闲时钟频率感到偏执)。
testloop是一个带有手写 asm 循环的静态可执行文件,其中包含 times 20 rdtsc (NASM 重复运算符)和 dec ebp/jnz , 循环的顶部按 64 对齐,以防万一。在循环之前,mov ebp, 10000000初始化计数器。 (有关我如何以这种方式进行微基准测试的详细信息,请参阅 Can x86's MOV really be "free"? Why can't I reproduce this at all?。或者 Understanding the impact of lfence on a loop with two long dependency chains, for increasing lengths 另一个简单的 NASM 程序示例,其中使用 times 来重复指令的循环。)

 Performance counter stats for './testloop' (2 runs):

1,278.19 msec task-clock:u # 1.000 CPUs utilized ( +- 0.19% )
4 context-switches # 0.004 K/sec ( +- 11.11% )
0 cpu-migrations # 0.000 K/sec
2 page-faults # 0.002 K/sec
5,243,270,118 cycles:u # 4.102 GHz ( +- 0.01% ) (71.37%)
219,949,542 instructions:u # 0.04 insn per cycle ( +- 0.01% ) (85.68%)
10,000,692 branches:u # 7.824 M/sec ( +- 0.03% ) (85.68%)
32 branch-misses:u # 0.00% of all branches ( +- 93.65% ) (85.68%)
4,010,798,914 uops_issued.any:u # 3137.885 M/sec ( +- 0.01% ) (85.68%)
4,010,969,168 uops_executed.thread:u # 3138.018 M/sec ( +- 0.00% ) (85.78%)
0 cpu_clk_thread_unhalted.one_thread_active:u # 0.000 K/sec (57.17%)

1.27854 +- 0.00256 seconds time elapsed ( +- 0.20% )


Performance counter stats for './testloop' (2 runs):

1,278.26 msec task-clock:u # 1.000 CPUs utilized ( +- 0.18% )
6 context-switches # 0.004 K/sec ( +- 9.09% )
0 cpu-migrations # 0.000 K/sec
2 page-faults # 0.002 K/sec ( +- 20.00% )
5,245,894,686 cycles:u # 4.104 GHz ( +- 0.02% ) (71.27%)
220,011,812 instructions:u # 0.04 insn per cycle ( +- 0.02% ) (85.68%)
9,998,783 branches:u # 7.822 M/sec ( +- 0.01% ) (85.68%)
23 branch-misses:u # 0.00% of all branches ( +- 91.30% ) (85.69%)
4,010,860,476 uops_issued.any:u # 3137.746 M/sec ( +- 0.01% ) (85.68%)
4,012,085,938 uops_executed.thread:u # 3138.704 M/sec ( +- 0.02% ) (85.79%)
4,174 cpu_clk_thread_unhalted.one_thread_active:u # 0.003 M/sec ( +- 9.91% ) (57.15%)

1.27876 +- 0.00265 seconds time elapsed ( +- 0.21% )

与单独运行:
 Performance counter stats for './testloop' (2 runs):

1,223.55 msec task-clock:u # 1.000 CPUs utilized ( +- 0.52% )
4 context-switches # 0.004 K/sec ( +- 11.11% )
0 cpu-migrations # 0.000 K/sec
2 page-faults # 0.002 K/sec
5,003,825,966 cycles:u # 4.090 GHz ( +- 0.00% ) (71.31%)
219,905,884 instructions:u # 0.04 insn per cycle ( +- 0.04% ) (85.66%)
10,001,852 branches:u # 8.174 M/sec ( +- 0.04% ) (85.66%)
17 branch-misses:u # 0.00% of all branches ( +- 52.94% ) (85.78%)
4,012,165,560 uops_issued.any:u # 3279.113 M/sec ( +- 0.03% ) (85.78%)
4,010,429,819 uops_executed.thread:u # 3277.694 M/sec ( +- 0.01% ) (85.78%)
28,452,608 cpu_clk_thread_unhalted.one_thread_active:u # 23.254 M/sec ( +- 0.20% ) (57.01%)

1.22396 +- 0.00660 seconds time elapsed ( +- 0.54% )

( cpu_clk_thread_unhalted.one_thread_active:u 的计数器仅以较慢的速度计数;系统在此测试期间相当空闲,因此它应该一直拥有自己的核心。即,~23.2 M 计数/秒确实代表单线程模式。 )

与一起运行的 0 和接近 0 的计数相比,我成功地让这些任务在同一核心上同时运行,使用超线程,基本上整个时间(约 1.2 秒重复两次,或 2.4 秒)。

因此,每个 RDTSC 单线程 5.0038G 周期/10M 迭代/20 rdtsc/iter = 25.019 周期,这与 Agner Fog 测量的差不多。

对 HT 测试的两个进程求平均值,即平均约 5.244G 周期/10M iter/20 rdtsc/iter = 26.22 个周期。

因此,在 Skylake 上同时在两个逻辑核心上运行 RDTSC 可提供近乎线性的加速,对吞吐量资源的竞争非常小。 无论 RDTSC 的瓶颈是什么,这都不是两个线程竞争或彼此减慢速度的东西。

让另一个核心忙于运行高吞吐量代码(如果它自己有一个核心,则可以维持每个时钟 4 uop)可能会比另一个也只运行 RDTSC 的线程对 RDTSC 线程造成更大的伤害。也许我们甚至可以弄清楚 RDTSC 是否需要比其他端口更多的特定端口,例如端口 1 很容易饱和,因为它是唯一可以运行整数乘法指​​令的端口。

关于x86 - 不同的进程可以同时运行RDTSC吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56439714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com