装配性能调整

2024-01-01

我正在编写一个编译器(更多的是为了好玩),但我想尝试使其尽可能高效。例如,我被告知在英特尔架构上使用除EAX执行数学运算会产生成本(大概是因为它交换为EAX进行实际的数学计算)。这里至少有一个来源说明了这种可能性(http://www.swansontec.com/sregisters.html)。

我想验证并测量这些性能特征的差异。因此,我用 C++ 编写了这个程序:

#include "stdafx.h"
#include <intrin.h>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    __int64 startval;
    __int64 stopval;
    unsigned int value; // Keep the value to keep from it being optomized out

    startval = __rdtsc(); // Get the CPU Tick Counter using assembly RDTSC opcode

    // Simple Math: a = (a << 3) + 0x0054E9
    _asm {
        mov ebx, 0x1E532 // Seed
        shl ebx, 3
        add ebx, 0x0054E9
        mov value, ebx
    }

    stopval = __rdtsc();
    __int64 val = (stopval - startval);
    cout << "Result: " << value << " -> " << val << endl;

    int i;
    cin >> i;

    return 0;
}

我尝试过这个代码交换eax and ebx但我没有得到“稳定”的数字。我希望测试是确定性的(每次都是相同的数字),因为它太短了,以至于在测试过程中不太可能发生上下文切换。目前来看,不存在统计差异,但数字波动如此之大,以至于无法做出这样的决定。即使我采集了大量样本,数量仍然有不可能的变化。

我也想测试一下xor eax, eax vs mov eax, 0,但有同样的问题。

有没有办法在 Windows(或其他任何地方)上进行此类性能测试?当我过去为我的 TI-Calc 编写 Z80 程序时,我有一个工具,我可以在其中选择一些程序集,它会告诉我执行代码需要多少个时钟周期——难道我们的新型现代处理器不能做到这一点吗?

编辑:有很多答案表明要运行循环一百万次。澄清一下,这实际上让事情变得更糟。 CPU 更有可能进行上下文切换,并且测试涉及除我正在测试的内容之外的所有内容。


即使希望获得 RDTSC 提供的可重复、确定的时序,您也需要采取一些额外的步骤。首先,RDTSC 是not序列化指令,因此它可以乱序执行,这通常会使其在像上面这样的代码片段中毫无意义。

您通常需要使用序列化指令,然后是 RDTSC,然后是有问题的代码,另一个序列化指令,以及第二个 RDTSC。

用户模式下几乎唯一可用的序列化指令是CPUID。然而,这又增加了一个小问题:CPUID 被英特尔记录为需要不同的执行时间——前几次执行可能比其他执行慢。

因此,代码的正常时序将如下所示:

XOR EAX, EAX
CPUID
XOR EAX, EAX
CPUID
XOR EAX, EAX
CPUID            ; Intel says by the third execution, the timing will be stable.
RDTSC            ; read the clock
push eax         ; save the start time
push edx

    mov ebx, 0x1E532 // Seed // execute test sequence
    shl ebx, 3
    add ebx, 0x0054E9
    mov value, ebx

XOR EAX, EAX      ; serialize
CPUID   
rdtsc             ; get end time
pop ecx           ; get start time back
pop ebp
sub eax, ebp      ; find end-start
sbb edx, ecx

我们已经开始接近这一目标,但最后一点是在大多数编译器上使用内联代码很难处理:交叉缓存行也可能会产生一些影响,因此您通常希望强制代码与 16 对齐-字节(段落)边界。任何像样的汇编器都会支持这一点,但编译器中的内联汇编通常不会。

说了这么多,我认为你是在浪费时间。正如你可以猜到的,我已经在这个级别上做了相当多的计时,并且我很确定你所听到的完全是一个神话。事实上,所有最新的 x86 CPU 都使用一组所谓的“重命名寄存器”。长话短说,这意味着您为寄存器使用的名称实际上并不重要——CPU 有一组更大的寄存器(例如,Intel 大约有 40 个)用于实际操作,因此在 EBX 与 EAX 中输入值对 CPU 真正要在内部使用的寄存器几乎没有影响。两者都可以映射到任何重命名寄存器,主要取决于该指令序列开始时哪些重命名寄存器恰好是空闲的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

装配性能调整 的相关文章

  • 如何使用C从http下载文件?

    最近几天我试图弄清楚如何从 URL 下载文件 这是我对套接字的第一个挑战 我用它来了解协议 所以我想在没有 cURL 库的情况下只用 C 语言来完成它 我搜索了很多 现在我可以打印页面的源代码 但我认为这与文件不同 我不必只将接收到的数据从
  • SOAP Web 服务:多台服务器,一个接口

    我有一个场景 需要任意数量的服务器来提供相同的 SOAP Web 服务 我想生成一组代理类 并能够为它们提供一个位置 以便在运行时将它们指向不同的服务器 不幸的是 看起来好像wsdl port节点 子节点wsdl service 要求对特定
  • ANTLR 中的布尔和算术表达式语法

    我正在尝试编写算术和布尔表达式的语法 我不明白我做错了什么 对于我的语法 ANTLR 说 致命 规则logic atom 由于可从 alts 1 2 到达的递归规则调用而具有非 LL 决策 通过左分解或使用语法谓词或使用 backtrack
  • 从结构调用 C++ 成员函数指针

    我找到了有关调用 C 成员函数指针和调用结构中的指针的信息 但我需要调用结构内部存在的成员函数指针 但我无法获得正确的语法 我在类 MyClass 的方法中有以下代码片段 void MyClass run struct int MyClas
  • 如何以编程方式删除受信任的根证书颁发机构中的证书?

    我需要能够从组织中的每台电脑中删除特定的证书 是的 我可以逐个座位 但我要到周四才能完成 而且我没有人力逐个座位 是否有使用 C 的编程方式来执行此操作 我认为你不需要编写任何 C 看看certmgr exe del http msdn m
  • Visual Studio 2013 调试器显示 std::string 的奇怪值

    我有一个大型的 cmake 生成的解决方案 其中包含许多项目 由于某种原因 我无法查看字符串的内容 因为根据调试器 Bx Buf含有一些垃圾 text c str 正确返回 Hello 该问题不仅仅发生在本地字符串上 返回的函数std st
  • 我担心我添加了太多接口

    我正在构建我的领域模型并继续重构它 正如我所做的那样 我发现我喜欢接口 因为它允许我根据接口为具体类型创建可重用的方法 控制器 视图 但是 我发现每次向域实体之一添加新属性时 我都会创建一个接口 例如 我有一个会员状态从抽象继承的对象Ent
  • 加载 QPixmap 数据的更好方法

    更好的方法来做到这一点 没有QImage QImage image width height QImage Format RGB888 memcpy image bits m frameRGB gt data 0 height width
  • 公交车公共交通算法

    我正在开发一个可以查找公交路线的离线 C 应用程序 我可以提取时间表 巴士 路线数据 我正在寻找适用于基本数据的最简单的解决方案 可以使用什么算法来查找从巴士站 A 到巴士站 B 的路线 是否有适用于 C Java 的开源解决方案 数据库的
  • 如何在 C 中链接目标文件?失败并显示“架构 x86_64 的未定义符号”

    因此 我尝试在我的文件 file2 c 中使用另一个 C file1 c 文件中定义的函数 为了做到这一点 我包含了 file1 file1 h 的标头 但是 每当我尝试使用 gcc 编译文件时 我都会收到以下错误 Undefined sy
  • DateTime.ParseExact - 为什么 yy 变成 2015 而不是 1915

    为什么 NET 假定以下年份是 2015 年 而不是 1915 年 var d DateTime ParseExact 20 11 15 dd MM yy new CultureInfo en GB 我想 它会尝试接近 但其背后是否有合理的
  • 当我尝试传递临时地址作为参数时,它是一个 UB 吗?

    对于以下 C 代码 include
  • main.cpp 是必需的吗?

    我试图编译一个程序cmake 我最终删除了我的main cpp文件 我刚刚将其复合到另一个包含我的项目名称的文件中 即 我刚刚将主函数剪切并粘贴到该文件中 问题是我有一个main cpp未发现错误 不确定是否在C 一个名为main cpp是
  • 运行实体框架自定义工具,它有什么作用?

    在 Visual Studio 中 当使用实体框架并为 tt 和 Context tt 文件应用运行自定义工具时 它是什么以及它有什么作用 为什么它解决数据库同步问题 有时 为什么我应该在运行 tt 之前运行它 Context tt 它被称
  • 如何在Windows窗体中打开进程

    我想在我的 Windows 窗体应用程序中打开进程 例如 我希望当用户按下 Windows 窗体容器之一中的按钮时 mstsc exe 将打开 如果他按下按钮 它将在另一个容器上打开 IE DllImport user32 dll SetL
  • 从单应性估计 R/T

    我一直在尝试计算 2 个图像中的特征 然后将这些特征传递回CameraParams R没有运气 特征已成功计算并匹配 但是问题是将它们传递回R t 我明白你必须分解Homography为了使这一点成为可能 我已经使用如下方法完成了 http
  • 异步/等待 - 是*并发*吗?

    我一直在考虑 C 5 中新的异步内容 并且出现了一个特殊问题 据我了解 await关键字是一个简洁的编译器技巧 语法糖来实现连续传递 http en wikipedia org wiki Continuation passing style
  • 跟踪白色背景中的白球(Python/OpenCV)

    我在 Python 3 中使用 OpenCV 来检测白场上的白 黑球 并给出它的精确 x y 半径 和颜色 我使用函数 cv2 Canny 和 cv2 findContours 来找到它 但问题是 cv2 Canny 并不总是检测到圆的完整
  • 将同步 zip 操作转换为异步

    我们有一个现有的库 其中一些方法需要转换为异步方法 但是我不确定如何使用以下方法执行此操作 错误处理已被删除 该方法的目的是压缩文件并将其保存到磁盘 请注意 zip 类不公开任何异步方法 public static bool ZipAndS
  • NHibernate:无状态会话错误消息无法获取代理

    我正在使用 nHibernate 无状态会话来获取对象 更新一个属性并将对象保存回数据库 我不断收到错误消息 无状态会话无法获取代理 我在其他地方有类似的代码 所以我不明白为什么这不起作用 有谁知道问题可能是什么 我正在尝试更新Screen

随机推荐

  • R 中使用 sf 和 sp 的投影差异

    我有一个已从 GeoTIFF 转换为 shapefile 的网格 我想将 shapefile 转换并导出为 GeoPackage 并更改投影 以便在 GIS 中打开时使用英国国家网格作为地理坐标系 然而 这似乎只能使用sp并不是sf 似乎没
  • HADOOP YARN - 应用程序已添加到调度程序,但尚未激活。由于集群资源为空而跳过 AM 分配

    我正在评估一个项目的 YARN 我正在尝试让简单的分布式 shell 示例正常工作 我已将应用程序提交到 已提交 阶段 但它从未启动 这是从这一行报告的信息 ApplicationReport report yarnClient getAp
  • _WIN64 未在 x64 项目中定义

    我使用的是 VS2008 项目属性设置为 活动 x64 奇怪的是 WIN64 没有定义 WPARAM 和 LPARAM 仍然是 32 位 我应该手动定义 WIN64吗 如果是这样 我应该把 define WIN64放在哪里 预处理器设置似乎
  • MS Word JavaScript API - 内容控件的事件处理程序

    有没有办法在单击 Office js 中的 contentControl 时触发函数 我正在为 MS Word 编写一个加载项 并且已插入内容控件 这些控件将与我的加载项中的列表关联 我需要在单击内容控件时触发一个函数 以便我可以滚动到列表
  • React-router 6 导航到使用参数

    在 v5 中我有这样的结构 path someurl id exact true render params gt
  • 在哪里可以找到 Mac OS X Lion 的“make”程序?

    刚刚将我的计算机升级到 Mac OS X Lion 然后进入终端并输入 make 但它显示 bash make 找不到命令 make 命令去哪儿了 您需要从以下位置安装 Xcode应用商店 http itunes apple com us
  • 需要隐藏 ansible 任务中失败的登录

    我是 ansible 任务的新手 正在创建一个执行登录操作的 yml 如果登录失败 则需要调用一些脚本 name Logging Action shell usr local bin cqlsh u xyzyx p 1234abc regi
  • 直觉类型理论的组合逻辑等价物是什么?

    我最近完成了一门以 Haskell 和 Agda 一种依赖类型函数编程语言 为特色的大学课程 并且想知道是否有可能用组合逻辑代替其中的 lambda 演算 在 Haskell 中 使用 S 和 K 组合器似乎可以实现这一点 从而使其成为无点
  • java 解析布尔值可能为空的布尔值

    我注意到一个问题java lang 布尔值 https docs oracle com javase 7 docs api java lang Boolean html类无法解析空值 我知道它有parseBoolean https docs
  • 如何隐藏

    我试图隐藏这些 p p
  • Lollipop 的应用程序兼容性、兼容性和支持库(如果最低 SDK = 14)

    我们有一个现有的 Android 应用程序 支持 API 级别 8 至 18 我们使用兼容性库 19 1 0 现在我们正在更改 升级为 最低 SDK 14 目标 android 22 现在考虑到不同版本都有 v4 v7 v13 支持 兼容性
  • ResolveEventArgs.RequestingAssembly 为 Null

    我正在尝试通过反射动态加载程序集 我有这样的文件夹结构 project BIN myApp exe SOMEEXTENTION1 someExtention1 dll itsDependency1 dll SOMEEXTENTION2 so
  • R 以编程方式更改 IP 地址

    目前通过将不同的字符串传递给来更改 user agenthtml session method 还有一种方法可以在抓取网站时更改计时器上的 IP 地址吗 您可以通过以下方式使用代理 它会更改您的IP use proxy如下 html ses
  • Cucumber + 测试 JS 警报

    我正在尝试使用 Cucumber on Rails 测试 JS 确认对话框 我有一个 window onbeforeunload 事件处理程序 如果您尝试离开该页面 它会提示您一个确认对话框 但我不知道如何测试它 有人知道如何做到这一点吗
  • 我可以使用最新的稳定 TypeScript 还是应该坚持使用 AngularCLI 附带的版本?

    我找不到任何关于是否使用可用的最新稳定版本升级 TypeScript 版本的官方建议 npm 版本自动设置在package json创建新项目时通过 AngularCLI 目前是 typescript 2 4 2 这意味着最新的2 4 x版
  • 在单个 ROC 图上绘制线性判别分析、分类树和朴素贝叶斯曲线

    数据显示在页面的最底部 称为 LDA scores 这是一个分类任务 我在数据集上执行了三种监督机器学习分类技术 提供所有编码以显示这些 ROC 曲线是如何生成的 我很抱歉提出了一个有问题的问题 但近两周来我一直在尝试使用不同的代码组合来解
  • 如何合并多个 BIRT 报告

    我们目前拥有一整套报告设计 涵盖了我们应用程序的各个部分 并且这些报告是根据用户的需求生成的 我希望能够将其中几个报告捆绑成一个报告以返回给用户 我最初破解了一个自定义报告生成器 它使用报告库文件中的段生成报告设计文件 然后运行生成的设计
  • 在 PERL 中从 Windows 访问 Microsoft SQL Server

    我正在使用 SQL Server 驱动程序 但这是我得到的以下错误 DBI connect Driver SQL Server database host cartertest failed Microsoft ODBC Driver Ma
  • 如何使用另一个模块的反应式数据帧更新闪亮模块

    该模块的目标是创建一个根据数据选择器模块的输出而变化的反应性条形图 不幸的是 条形图没有更新 它停留在选定的第一个变量上 我尝试创建观察者函数来更新条形图 但无济于事 我还尝试将选择器服务器模块嵌套在 barplot 模块中 但出现错误 警
  • 装配性能调整

    我正在编写一个编译器 更多的是为了好玩 但我想尝试使其尽可能高效 例如 我被告知在英特尔架构上使用除EAX执行数学运算会产生成本 大概是因为它交换为EAX进行实际的数学计算 这里至少有一个来源说明了这种可能性 http www swanso