【问题标题】:sleep without system or IO calls在没有系统或 IO 调用的情况下休眠
【发布时间】:2014-03-18 10:40:29
【问题描述】:

对于具有硬件事务内存的场景,我需要一个不会发出任何系统或 IO 调用的睡眠(这些调用会导致中止)。在usleep(1) 中休眠 1 微秒就可以了。

This question 建议实现嵌套循环以保持程序繁忙并延迟一段时间。但是,我希望能够通过删除这些循环的优化进行编译。

一个想法可能是计算一些复杂的数学方程。有没有办法解决这个问题?实际等待的时间不必很精确 - 但是多次运行应该大致相同。

【问题讨论】:

  • 清醒的时间(例如计算一个循环或执行一个冗长的方程式)不是睡眠。
  • 我假设您在 Intel 的 TSX 上?
  • 另外,我很好奇您的用例:延长事务生命周期通常是个坏主意,因为它会不必要地增加冲突的可能性——除非这是重点?
  • @MatthewG.:是的,它是英特尔的 TSX(具体使用 HLE)。你是对的,冲突的概率增加是这里比较两种算法在不同事务运行时方面的重点。
  • 嗯,看看这个结果会很有趣。最美好的祝愿!

标签: c++ sleep transactional-memory


【解决方案1】:

尝试使用 volatile asm 指令的 nop 循环:

for (int i = 0; i < 1000; i++) { 
    asm volatile ("nop"); 
} 

volatile 应该防止优化器摆脱它。如果还是不行,那么试试__volatile__

【讨论】:

  • 这有效且不会导致中止 - 谢谢! (对于usleep(1):1000 个循环 ~ 1 微秒在我的系统上)
  • 太棒了。很高兴听到它。
【解决方案2】:

这里的棘手部分是时机。查询任何类型的计时器都可能算作 I/O 函数,具体取决于操作系统。

但是,如果您只想要一个延迟循环,那么当时间不那么重要时,您应该查看特定于平台的代码。例如,有一个名为 _mm_pause 的 Intel 特定内在函数,它转换为 CPU 的 pause 指令,它基本上会暂停流水线,直到下一次内存总线同步通过。它被设计为放入自旋锁循环中(在有可能获得新信息之前,旋转和重新查询原子变量没有意义),但它可能(可能 - 阅读文档)抑制编译器将您的延迟循环删除为空。

【讨论】:

  • 唉,这行不通。在 TSX 文档中,PAUSE 被列为将在任何 TSX 实现中无条件中止事务的指令之一。
【解决方案3】:

您可以使用此代码:

#include <time.h>

void delay(int n)
{
    n *= CLOCKS_PER_SEC / 1000;
    clock_t t1 = clock();
    while (clock() <= t1 + n && clock() >= t1);
}

有时(不经常)由于时钟计数器溢出,此函数会导致小于指定的延迟。

更新

另一种选择是使用this 之类的循环和volatile 计数器。

【讨论】:

  • 不幸的是clock() 一个系统调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-22
  • 2012-03-15
  • 2016-05-19
  • 2015-10-19
相关资源
最近更新 更多