- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我添加一段代码来测量 CPU 执行时间时,例如:
int main()
{
clock_t init_time = clock(); // (1)
your_fun(); // (2)
printf("Seconds: %f", (double)(clock() - init_time) / CLOCKS_PER_SEC); // (3)
}
如果我以完全优化的方式编译那段代码,是否可以将代码重新排序,使 init_time
初始化在 your_fun
之后执行,这样你就什么都不测量了?换句话说,clock
是否有任何内存屏障机制来保护测量 block 不被重新排序?
如果 clock
不是抗重排序的:如果我将 (1) 和 (3) 移动到在不同编译单元中实现的新函数,那么编译器在编译 main
, 看不到里面的东西,能不能防止这样的重排序?
我一直有这个问题,因为我通常会看到等待执行的时间(秒)与打印的执行时间(毫秒甚至 0)之间相互矛盾的执行时间。
C++ 时钟或本地时间函数怎么样?他们有类似的问题吗?
最佳答案
对时间读取函数的调用是系统调用:测量将准确地发生在正确的位置,相对于其他系统调用,包括 I/O 操作。这不是您要的:您正在为一个纯操作计时,一个没有 SE(副作用)的计算。
您希望计算恰好发生在两个系统调用之间的正确位置;您需要订购它,而不是完全优化它。
像往常一样,要阻止优化,请使用volatile:所有volatile操作都是副作用,就像一个系统调用(比如调用read
或write
)。
注意:您可能指望真正的单独编译来达到同样的效果;那是如果您确定不会应用全局程序优化。
根据定义,副作用永远无法重新排序。此外, volatile 读取具有不确定的值,即使是常量也是如此:
const volatile int indeterminate_zero = 0;
任何表达式中 indeterminate_zero
的每个实例都会产生编译器无法假定为 0 的 0。
您需要将计算与副作用放在一起,并使其依赖于未知值,以便计算准确地发生在您想要的位置。
在正确的位置插入 volatile 操作将以普通内存读取或写入的微不足道的成本做到这一点:对 volatile 全局整数类型的操作与常规(非 volatile)的成本完全一样) 在几乎所有编译器上禁用优化的类似操作。
重要的是,您将 volatile 读取视为特殊的 scanf
并将写入视为特殊的 printf
,两者都不与任何 STDIO 流交互,并且它们的成本都极低,并且比调用普通系统调用(如 getpid
、getppid
、0 字节的 write
...)更可移植。
(我没有发布带有可编译代码的完整答案,因为您没有提出带有我可以重新表述的可运行代码的完整问题。)
如果您不想打扰所有这些,只需使用单独的编译即可。所有常用的编译器都支持单独编译(编译器可以合法地强制您一次提交所有代码,但据我所知,没有一个这样做)。
关于c++ - 使用C时间函数测量时间: are they code-reordering resistant?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67370546/
这是对 Reordering factor gives different results, depending on which packages are loaded 的跟进,还有另一个相关问题。
我最近一直在摆弄数组和数组排序,并偶然发现了一些奇怪的东西。 以这种情况为例: arr = {}; arr[1] = "one"; arr[2] = "two"; arr[105] = "three"
题目地址:https://leetcode.com/problems/reorder-list/description/ 题目描述: Given a singly linked list L: L
我使列表可重新排序,但现在又回到了初始状态。有人能帮我吗?我的列表包含列表磁贴,它是使用Asynsnapshot从数据库生成的。我使用的键与索引相同。似乎insert函数没有在新索引中插入注释。是因为
我很困惑为什么箱线图在此图中没有排序: set.seed(200) x <- data.frame(country=c(rep('UK', 10),
我有一个或多或少作为列表显示给用户的实体列表。现在,用户不仅可以添加或删除实体,还可以对现有实体重新排序(使用典型的“向上”、“向下”、“转到顶部”、“转到底部”操作)。 但是实现这种行为的最佳方式是
我正在尝试使用 Bootstrap 3 制作如下所示的网格。 目标 SM 医学博士 方法一 Content1
我有如下表格, | id | name | color | ------+--------+--------- | 1 | pear | green | | 2 | apple
似乎对 SQLite3 表中的列进行重新排序并不简单。至少 Firefox 中的 SQLite Manager 不支持此功能。例如,将 column2 移动到 column3,将 column5 移动
我的抽屉导航中列出了许多页面/fragment ,用户可能会经常在这些页面/fragment 之间切换,我希望它们在后台堆栈中以便他们可以导航回来,但我只想要每个 fragment 的一个实例后台堆栈
当我添加一段代码来测量 CPU 执行时间时,例如: int main() { clock_t init_time = clock(); // (1) your_fun(); // (2)
当用户更改顺序时,我需要同步两个 ListViews 事件的列顺序。但似乎没有列重新排序事件。 目前我只是做了一个 AllowsColumnReorder="False"但这不是一个永久的解决方案。在
我很难理解 reorder() 背后的逻辑。 假设 Var 定义如下: Var data(iris) > head(iris) Sepal.Length Sepal.Width Petal.Le
我正在创建一个 WPF 数据网格,我希望能够通过拖放重新排序行,如下所示:我单击一行并将其向上或向下拖动。正如我所做的那样,如果我释放鼠标,一个标记会显示行将被放置的位置。当我释放鼠标时,拖动的行被插
我想重新排序我的列表,但出现此错误。 此小部件的所有子项都必须在 Reorderable Listview 中有一个键 Widget list(list) { return Scrollbar
我想重新排序我的列表,但出现此错误。 此小部件的所有子项都必须在 Reorderable Listview 中有一个键 Widget list(list) { return Scrollbar
在我的数据库中我有如下三个表: 任务(TaskID、TaskName、TaskDescription) TaskDetails(TaskID、subTaskPosition、SubTaskID) 子任
我仍在使用 https://github.com/syntagmatic/parallel-coordinates#parallel-coordinates 绘制平行坐标图和 d3.js 轴重新排序后
我正在阅读Kyle Simpson's book (You don't Know JS - ES6 and beyond)他给出了有关重新排序数组的示例: var a1 = [ 1, 2, 3 ],
我的领域对象: public class MyDomainObject { public Guid Id { get; set; } public string Name { get;
我是一名优秀的程序员,十分优秀!