- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个C代码,用于测量获取信号量所需的时钟周期数。我正在使用rdtsc,在对信号量进行测量之前,我连续两次调用rdtsc来测量开销。我在for循环中重复了很多次,然后将平均值用作rdtsc开销。
首先使用平均值是正确的吗?
但是,这里最大的问题是,有时我得到的开销为负值(不一定是平均值,而至少是for循环内的部分值)。
这也会影响sem_wait()
操作所需的cpu周期数的连续计算,有时甚至会为负数。如果我写的内容不清楚,这就是我正在处理的部分代码。
为什么我会得到这样的负值?
(编者注:有关获取完整的64位时间戳的正确且可移植的方法,请参见Get CPU cycle count?。
"=A"
输出选择了RAX或RDX。而不会选择
uint64_t
。)
(编辑器的第二个注释:哎呀,这就是为什么我们得到负面结果的答案。仍然值得在此处留下注释,以警告您不要复制此
edx:eax
实现。)
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
static inline uint64_t get_cycles()
{
uint64_t t;
// editor's note: "=A" is unsafe for this in x86-64
__asm volatile ("rdtsc" : "=A"(t));
return t;
}
int num_measures = 10;
int main ()
{
int i, value, res1, res2;
uint64_t c1, c2;
int tsccost, tot, a;
tot=0;
for(i=0; i<num_measures; i++)
{
c1 = get_cycles();
c2 = get_cycles();
tsccost=(int)(c2-c1);
if(tsccost<0)
{
printf("#### ERROR!!! ");
printf("rdtsc took %d clock cycles\n", tsccost);
return 1;
}
tot = tot+tsccost;
}
tsccost=tot/num_measures;
printf("rdtsc takes on average: %d clock cycles\n", tsccost);
return EXIT_SUCCESS;
}
最佳答案
英特尔首次发明TSC时,它测量的是CPU周期。由于各种电源管理功能,“每秒循环数”不是恒定的;因此,TSC最初对衡量代码的性能有好处(而对测量经过的时间不利)。
不论好坏那时,CPU并没有真正进行过多的电源管理,无论如何,CPU通常以固定的“每秒循环数”运行。一些程序员有一个错误的想法,并误用了TSC来测量时间而不是周期。后来(当电源管理功能的使用变得越来越普遍时),这些人滥用TSC来测量时间时,他们就误解了由滥用引起的所有问题。 CPU制造商(从AMD开始)更改了TSC,因此它测量的是时间而不是周期(使之无法测量代码性能,但可以正确测量经过的时间)。这引起了混乱(软件很难确定TSC实际测量的是什么),因此稍后在AMD上,CPUID上添加了“ TSC Invariant”标志,因此,如果设置了此标志,程序员将知道TSC已损坏(用于测量)。周期)或固定(用于测量时间)。
英特尔遵循AMD并更改了TSC的行为以测量时间,并采用了AMD的“ TSC不变”标志。
这给出了4种不同的情况:
TSC衡量时间和性能(每秒周期数不变)
TSC衡量绩效而不是时间
TSC测量时间而不是性能,但不使用“ TSC不变”标志来表示
TSC测量时间而不是性能,并且确实使用“ TSC不变”标志来表示(大多数现代CPU)
对于TSC测量时间的情况,要正确地测量性能/周期,您必须使用性能监视计数器。遗憾的是,性能监控计数器针对不同的CPU(特定于型号)有所不同,并且需要访问MSR(特权代码)。这使得应用程序无法测量“周期”。
还要注意,如果TSC确实测量了时间,您将无法知道它返回的时间标度(“假装周期”中有多少纳秒),而无需使用其他时间源来确定标度因子。
第二个问题是,对于多CPU系统,大多数操作系统都比较糟糕。操作系统处理TSC的正确方法是防止应用程序直接使用它(通过在CR4中设置TSD
标志;这样RDTSC指令会导致异常)。这样可以防止各种安全漏洞(定时辅助通道)。它还允许操作系统模拟TSC并确保其返回正确的结果。例如,当应用程序使用RDTSC指令并引起异常时,操作系统的异常处理程序可以找出要返回的正确“全局时间戳”。
当然,不同的CPU都有自己的TSC。这意味着,如果应用程序直接使用TSC,它们将在不同的CPU上获得不同的值。帮助人们解决操作系统无法解决的问题(通过像他们应该的那样模拟RDTSC); AMD添加了RDTSCP
指令,该指令返回TSC和一个“处理器ID”(英特尔最终也采用了RDTSCP
指令)。在损坏的操作系统上运行的应用程序可以使用“处理器ID”来检测它们何时与上次在不同的CPU上运行;并且以这种方式(使用RDTSCP
指令),他们可以知道何时“经过= TSC-previous_TSC”给出有效的结果。然而;该指令返回的“处理器ID”只是MSR中的一个值,操作系统必须将每个CPU上的该值设置为不同的值-否则RDTSCP
表示所有CPU上的“处理器ID”为零。
基本上;如果CPU支持RDTSCP
指令,并且OS正确设置了“处理器ID”(使用MSR);那么RDTSCP
指令可以帮助应用程序知道何时获得了不好的“经过时间”结果(但是它无法提供解决或避免不好的结果的方式)。
所以;简而言之,如果您想进行准确的性能测量,则几乎会一头雾水。实际上,您可以期望的最好结果是准确的时间测量;但仅在某些情况下(例如,在单CPU计算机上运行或“固定”到特定CPU上;或在检测到并丢弃无效值的操作系统上正确使用RDTSCP
设置了
当然,即使那样,由于IRQ之类的问题,您也将获得不可靠的度量。为此原因;最好在一个循环中多次运行您的代码,并丢弃任何比其他结果高得多的结果。
最后,如果您确实想正确执行此操作,则应该测量测量的开销。为此,您需要测量什么都不做(仅使用RDTSC / RDTSCP指令,而放弃不可靠的测量)。然后从“测量某物”结果中减去测量的开销。这使您可以更好地估计实际“花费”的时间。
注意:如果您可以从《奔腾》首次发布时(1990年代中期-不确定它是否现在可以在线使用-我从1980年代开始就存档了)中提取《英特尔系统编程指南》的副本,您会发现英特尔记录了时间戳记计数器是“可以用来监视和识别处理器事件发生的相对时间”的东西。他们保证(不包括64位环绕)它会单调增加(但不会以固定速率增加),并且至少要花10年才能环绕。手册的最新版本详细记录了时间戳计数器,指出对于较旧的CPU(P6,Pentium M,较旧的Pentium 4),时间戳计数器“随每个内部处理器时钟周期而增加”,而“ Intel(r) SpeedStep(r)技术的过渡可能会影响处理器时钟。”以及较新的CPU(较新的Pentium 4,Core Solo,Core Duo,Core 2,Atom),TSC均以恒定速率递增(这就是“前进的体系结构行为”)。本质上,从一开始,它就是一个(变量)“内部周期计数器”用于时间戳记(而不是一个用于跟踪“墙上时钟”时间的时间计数器),并且这种行为在2000年(基于Pentium 4的发布日期)。
关于c - 背对背rdtsc进行负时钟周期测量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19941588/
性能优化的重要性不言而喻,Google 的 研究表明 ,当网站达到核心 Web 指标(Core Web Vitals)阈值时,用户放弃加载网页的可能性会降低 24%。 如何
我正在创建一个横幅设计创建器(这样人们就可以使用自己的文本、背景、图像、形状等来制作自己的设计)。我的产品有各种尺寸,例如:800x2000 mm、A4(210 x 297mm)、3300x2200m
我不确定如何使用测量来获取单位的全名。例如“公里”而不是“公里”。 let measurement = Measurement(value: 50, unit: UnitLength.meters)
我有一个自定义 ViewGroup,它有一个子 ViewPager。 ViewPager 由 PagerAdapter 提供,该 LinearLayout 向 ViewPager 提供 LayoutP
我想测量一个大型软件项目在 Linux (make) 中构建过程中的内存消耗是多少内存。理想情况下,消耗会按操作(即编译、链接)拆分,但一开始绘制随时间变化的图表可能就足够了。 我有哪些选择? 最佳答
我正在运行一个 SSIS 包来从一个平面文件加载一百万行,它使用一个脚本任务进行复杂的转换和一个 SQL Server 表目标。我试图找出在数据流处理期间将行数(可能是 1000 的倍数以提高效率)写
我正在尝试检查 Keras 模型不同层的执行速度(使用来自 tensorflow 2.3.0 v 的 keras) 我从这个 repo 中获取了代码并修改它,使用 timer() from from
我有一个旧的应用程序,一个 JAR 文件,它经过了一些增强。基本上必须修改代码的某些部分以及修改一些逻辑。 将旧版本与新版本进行比较,新版本比旧版本慢约 2 倍。 我试图缩小导致速度变慢的原因,但我发
我正在尝试测量不同 Silverlight 图表库(例如 Silverlight Control Toolkit、Visifire、Telerik)在屏幕上加载所需的时间。 我的问题是我只能测量加载控
由于 TTFB 会因每个请求而异,因此我想对其进行统计并获取平均值。有谁知道我如何通过 PHP 进行测量?bytecheck.com 网站能够分析这些数据:这是 example.com 的示例:htt
我正在使用 .NET 4.0 C# 编写应用程序。我将对象放在 .net httpruntime 缓存中,并希望在其上生成一些统计信息。我想知道对象在放入缓存之前的大小以及它在缓存中的大小。我该如何衡
我正在寻找某种方法来测量应用程序的启动时间。从点击应用程序图标的那一刻到用户可以看到例如登录页面的那一刻。 最佳答案 跑 flutter run --trace-startup --profile 跟
我正在优化 iPhone 应用程序以实现非常短的加载时间,我想知道: 是否有一种方法可以测量 iPhone 应用程序从用户点击图标到应用程序可用(或至少 –viewDidLoad 被调用)的加载时间?
我无法理解 中的一件事谷歌分析 .我的应用中需要一个功能,例如 一个 用户将我的应用转至 乙用户然后他得到了一些奖励,但我想跟踪 一个 时通过链接的用户 ID乙用户点击该链接然后我可以得到一个 中的用
有没有办法用 DUnit 来衡量代码覆盖率?或者有没有免费的工具可以实现这一点?你用它做什么?您通常追求什么代码覆盖率? Jim McKeeth:感谢您的详细回答。我谈论的是 TDD 方法意义上的单元
当我执行Makefile时,是否可以递归地回荡在make all的每个目标中花费的(系统,用户,实际)时间? 我想以比time make all更细粒度的方式对项目的编译进行基准测试。理想情况下,它将
R 中有衡量函数执行时间的标准化方法吗? 显然我可以在执行之前和之后获取system.time,然后取它们的差异,但我想知道是否有一些标准化的方法或功能(不想发明轮)。 我似乎记得我曾经使用过如下的东
我最近为了好玩而开始学习 Fortran,我想知道是否有任何简单的方法来显示执行我的代码所花费的时间。这只是一个数到一百万的简单循环,我想看看完成这个需要多长时间。 如果有帮助,这是我正在使用的代码:
我正在开发一个 Shiny 的应用程序。 我对计算执行某些代码块(例如 ggplot 等)所需的时间很感兴趣。 出于某种原因,使用通常的时钟方法似乎在响应式(Reactive)调用中不起作用,例如:
我想测量 jpeg 的白色/黄色量(在可调整的容差范围内)。 我正在尝试开发一种质量控制工具来测量杏仁的缺陷。缺陷是棕色杏仁皮上的划痕(见下图)。由于这些缺陷是白色/黄色的,我想要一种简单地将图像加载
我是一名优秀的程序员,十分优秀!