- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要一种分析数字代码的更好方法。假设我在Cygwin的64位x86上使用GCC,并且我不打算购买商业工具。
情况就是这样。我在一个线程中运行一个函数。除内存访问外,没有代码依赖性或I / O,可能链接了一些数学库。但在大多数情况下,所有这些都是表查找,索引计算和数值处理。我已经缓存对齐堆和堆栈上的所有数组。由于算法的复杂性,循环展开和较长的宏,汇编清单可能变得很长-数千条指令。
我一直在使用Matlab中的tic / toc计时器,bash shell中的time实用程序,或者直接在函数周围使用时间戳计数器(rdtsc)。问题是这样的:时间的差异(可能占运行时间的20%)大于我正在进行的改进的大小,因此我无法知道代码的优劣。更改后。您可能会认为该放弃了。但是我不同意。如果您坚持不懈,那么许多增量改进可以使性能提高两到三倍。
我多次遇到的一个特别令人困扰的问题是我进行了更改,并且性能似乎持续提高了20%。第二天,收益损失了。现在有可能我做了我认为对代码无害的更改,然后完全忘记了它。但是我想知道是否有其他事情正在进行。就像我相信的那样,也许GCC不会产生100%的确定性输出。也许这更简单一些,例如OS将我的过程转移到了更繁忙的内核上。
我已经考虑了以下内容,但我不知道这些想法是否可行或有意义。如果是的话,我想明确说明如何实施解决方案。目标是最小化运行时的差异,以便我可以有意义地比较优化代码的不同版本。
将处理器的内核专用于仅运行例程。
直接控制缓存(加载或清除缓存)。
确保我的dll或可执行文件始终加载到内存中的同一位置。我的想法是,缓存的组关联性可能会与RAM中的代码/数据位置发生交互作用,从而改变每次运行时的性能。
某种周期精确的仿真器工具(非商业)。
是否可以对上下文切换进行一定程度的控制?还是有关系吗?我的想法是上下文切换的时间可能会导致变化,可能是因为在不适当的时间刷新了管道。
过去,通过统计汇编清单中的指令,我在RISC体系结构上取得了成功。当然,这仅在指令数量少的情况下有效。一些编译器(例如TI的C67x的Code Composer)将为您提供详细的分析方法,以使ALU保持忙碌状态。
我还没有发现GCC / GAS生产的装配清单特别有用。启用全面优化后,代码将遍及所有位置。对于在程序集列表中分散的单个代码块,可以有多个位置指令。此外,即使我能理解程序集如何映射回我的原始代码,也不确定在现代x86机器上指令数与性能之间是否存在很大的相关性。
我在尝试使用gcov进行逐行分析方面做得很差,但是由于我构建的GCC版本与MinGW编译器之间不兼容,因此无法正常工作。
您可以做的最后一件事是平均进行许多次试运行,但这需要永远。
编辑(RE:调用堆栈采样)
我的第一个问题是,实际上,我该怎么做?在其中一张幻灯片中,您展示了使用Visual Studio暂停程序。我所拥有的是由GCC编译的DLL,在cygwin中进行了全面优化。然后,由Matlab使用VS2013编译器编译的mex DLL调用此方法。
我使用Matlab的原因是因为我可以轻松地试验不同的参数并可视化结果,而无需编写或编译任何低级代码。此外,我可以将优化的DLL与高级Matlab代码进行比较,以确保优化不会破坏任何内容。
我使用GCC的原因是,与使用Microsoft的编译器相比,我拥有更多的经验。我熟悉许多标志和扩展名。此外,至少在过去,Microsoft不愿维护和更新本机C编译器(C99)。最后,我看到了GCC摆脱了商业编译器的束缚,并且我查看了汇编列表以了解其实际完成方式。因此,我对编译器的实际想法有一些直觉。
现在,关于猜测要解决的问题。这不是真正的问题。这更像是猜测如何解决。在此示例中,就像在数值算法中经常出现的那样,实际上没有I / O(不包括内存)。没有函数调用。几乎没有任何抽象。就像我坐在一块萨兰包装上。我可以看到下面的计算机体系结构,两者之间实际上没有任何关系。如果我重新汇总所有循环,我可能会将代码放在大约一页左右的位置上,并且几乎可以算出最终的汇编指令。然后,我可以对单个核能够执行的理论操作数进行粗略的比较,以了解我有多接近最佳状态。然后的麻烦是,我失去了展开时获得的自动矢量化和指令级并行化能力。展开后,装配清单太长,无法以这种方式进行分析。
关键是该代码实际上没有太多内容。但是,由于编译器和现代计算机体系结构的复杂性令人难以置信,因此即使在此级别上也要进行大量优化。但是我不知道有什么小变化会影响编译代码的输出。让我举几个例子。
第一个有点模糊,但是我敢肯定我已经看过几次了。您进行较小的更改即可获得10%的改进。您进行了另一个小更改,又获得了10%的改进。您撤消第一个更改,然后再获得10%的改进。 ??编译器优化既不是线性的也不是单调的。可能第二个更改需要一个额外的寄存器,这通过强制编译器更改其寄存器分配算法而破坏了第一个更改。也许,第二个优化以某种方式阻碍了编译器执行优化的能力,而该能力是通过撤消第一个优化来解决的。谁知道。除非编译器具有足够的内省性,可以在每个抽象级别上转储其全部分析,否则您将永远无法真正知道最终的汇编是如何完成的。
这是我最近发生的一个更具体的例子。我手动编码AVX内部函数以加快过滤器操作。我以为我可以展开外循环来提高指令级的并行度。我这样做了,结果是代码慢了一倍。发生的事情是没有足够的256位寄存器来处理。因此,编译器将结果临时保存在堆栈中,这会降低性能。
正如我在您提到的this post中提到的那样,最好告诉编译器您想要什么,但不幸的是,您通常别无选择,通常被迫通过猜测和检查来进行优化。
因此,我想我的问题是,在这些情况下(代码在展开之前实际上很小,每个性能的增量变化都很小,并且您正在以非常低的抽象水平进行工作),最好具有“精确的时间”还是调用堆栈采样能更好地告诉我哪个代码更好?
最佳答案
我是对的,您正在做的事情是对要解决的问题进行有根据的猜测,将其修复,然后尝试进行衡量以查看它是否有所不同?
我以不同的方式进行操作,当代码变大时,这种方法特别有效。
而不是猜测(我当然可以),我让程序通过使用this method告诉我如何度过时间。
如果该方法告诉我大约有30%的时间用于某某某事,那么我可以集中精力找到一种更好的方法。
然后,我可以运行它并对其进行计时。
我不需要很多精度。
如果更好,那就太好了。
如果情况更糟,我可以撤消更改。
如果是相同的话,我可以说:“哦,也许它并没有节省很多,但是让我们再做一次以找到另一个问题,”
我不用担心
如果有一种方法可以加快程序的速度,这将查明它。
通常,问题不只是一个简单的陈述,例如“行或例程X花费Y%的时间”,而是“这样做的原因是在某些情况下是Z”,而实际的解决方法可能在其他地方。
修复问题后,可以再次执行该过程,因为以前较小的另一个问题现在更大了(以百分比表示,因为通过修复第一个问题已减少了总数)。
重复是关键,因为每个加速因子都会乘以所有先前的因子,例如复利。
当程序不再指出我可以解决的问题时,我可以确定它几乎是最佳的,或者至少没有其他人可以击败它。
而且在此过程中,我根本不需要非常精确地测量时间。
然后,如果我想在PowerPoint中吹牛,也许我会做多个计时以获得较小的标准误差,但是即使那样,人们真正关心的还是整体加速因素,而不是精度。
关于c - 可预测地对单个函数进行性能分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40790903/
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
从以下网站,我找到了执行java AD身份验证的代码。 http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexcepti
似乎 melt 会使用 id 列和堆叠的测量变量 reshape 您的数据框,然后通过转换让您执行聚合。 ddply,从 plyr 包看起来非常相似..你给它一个数据框,几个用于分组的列变量和一个聚合
我的问题是关于 memcached。 Facebook 使用 memcached 作为其结构化数据的缓存,以减少用户的延迟。他们在 Linux 上使用 UDP 优化了 memcached 的性能。 h
在 Camel route ,我正在使用 exec 组件通过 grep 进行 curl ,但使用 ${HOSTNAME} 的 grep 无法正常工作,下面是我的 Camel 路线。请在这方面寻求帮助。
我正在尝试执行相当复杂的查询,在其中我可以排除与特定条件集匹配的项目。这是一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我正在尝试执行相当复杂的查询,我可以在其中排除符合特定条件集的项目。这里有一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我发现了很多嵌入/内容项目的旧方法,并且我遵循了在这里找到的最新方法(我假设):https://blog.angular-university.io/angular-ng-content/ 我正在尝试
我正在寻找如何使用 fastify-nextjs 启动 fastify-cli 的建议 我曾尝试将代码简单地添加到建议的位置,但它不起作用。 'use strict' const path = req
我正在尝试将振幅 js 与 React 和 Gatsby 集成。做 gatsby developer 时一切看起来都不错,因为它发生在浏览器中,但是当我尝试 gatsby build 时,我收到以下错
我试图避免过度执行空值检查,但同时我想在需要使代码健壮的时候进行空值检查。但有时我觉得它开始变得如此防御,因为我没有实现 API。然后我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异
尝试进行包含一些 NOT 的 Kibana 搜索,但获得包含 NOT 的结果,因此猜测我的语法不正确: "chocolate" AND "milk" AND NOT "cow" AND NOT "tr
我正在使用开源代码共享包在 iOS 中进行 facebook 集成,但收到错误“FT_Load_Glyph failed: glyph 65535: error 6”。我在另一台 mac 机器上尝试了
我正在尝试估计一个标准的 tobit 模型,该模型被审查为零。 变量是 因变量 : 幸福 自变量 : 城市(芝加哥,纽约), 性别(男,女), 就业(0=失业,1=就业), 工作类型(失业,蓝色,白色
我有一个像这样的项目布局 样本/ 一种/ 源/ 主要的/ java / java 资源/ .jpg 乙/ 源/ 主要的/ java / B.java 资源/ B.jpg 构建.gradle 设置.gr
如何循环遍历数组中的多个属性以及如何使用map函数将数组中的多个属性显示到网页 import React, { Component } from 'react'; import './App.css'
我有一个 JavaScript 函数,它进行 AJAX 调用以返回一些数据,该调用是在选择列表更改事件上触发的。 我尝试了多种方法来在等待时显示加载程序,因为它当前暂停了选择列表,从客户的 Angul
可能以前问过,但找不到。 我正在用以下形式写很多语句: if (bar.getFoo() != null) { this.foo = bar.getFoo(); } 我想到了三元运算符,但我认
我有一个表单,在将其发送到 PHP 之前我正在执行一些验证 JavaScript,验证后的 JavaScript 函数会发布用户在 中输入的文本。页面底部的标签;然而,此消息显示短暂,然后消失...
我是一名优秀的程序员,十分优秀!