我有一个对性能敏感的XCode C++项目,我正在使用CPU节流的技巧。我添加了以下代码:
// function to occupy a thread for an infinite amount of time
void coreEngager() {
while (true) {}
}
// call it in the background thread
std::thread t1(coreEngager);
// call it once the work is done
t1.detach();
这个小技巧可以提高计算速度约50%,这在我的情况下非常重要。但是我最近发现了一个问题--如果我试图在发布模式下运行项目,这段代码会崩溃。coreEngager
函数发生崩溃。我以前没有这个问题,现在在Linux和Windows上也没有这个问题。你能告诉我有什么变化或者如何在MacOS上使用CPU节流吗?
1条答案
按热度按时间vql8enpb1#
**我有时在基准测试时使用
pause
循环来保持CPU频率,但我不愿意在无限循环上浪费整个核心用于生产用途。**相反,调整CPU电源管理设置,或在安装指南中建议用户这样做。或者让你的程序(或单独的脚本)检查设置并推荐更改。在C中,没有I/O或
volatile
或atomic
操作的无限循环是未定义的行为。编译器可以删除它们(https://eel.is/cdraft/intro.progress#1),clang会主动地这样做。它不会为coreEngager()
函数发出asm指令,所以执行只福尔斯在二进制中的下一个函数中。这个C规则旨在帮助编译器在循环条件不平凡时,这样他们可能会遇到证明循环终止的麻烦。
有趣的事实:ISO C有一个不同的规则,如果循环条件是一个常量表达式,如
1
,无限循环是定义良好的。但是IIRC,clang在这种情况下有一个bug,仍然应用C规则。要真正解决这个问题,请在循环中放入一个空的
asm volatile("")
语句,以使编译器满意,而不管目标是什么,而无需实际运行额外的指令。Godbolt显示它可以按需要编译:
如果有一个AArch 64等价于x86
pause
,请使用它。可能没有,因为没有SMT AArch 64 CPU(多个逻辑核心共享一个物理核心),并且它们在自旋循环中没有内存顺序错误推测,因为它们没有x86的强有序内存模型。x86-compat内存模式下的M1除外;也许苹果有一个类似pause
的指令?我假设您正在为像Skylake这样的CPU进行调优,其中内存绑定代码可以让CPU降时钟,例如。在我的i7- 6700 k上,硬件P-state管理设置为
balance_power
或balance_performance
(与设置为完整performance
不同),而不是3.7GHz。(Slowing down CPU Frequency by imposing memory stress)或者你有其他线程有时完全休眠,没有旋转线程,它们最初以空闲频率出现?(* 为什么这个延迟循环在几次迭代之后运行得更快,而没有睡眠?* )
相关内容: