Questions tagged «optimization»

优化是改进现有程序以使其更有效地工作和/或使用较少资源的过程。

7
什么时候应该将工作转移到GPU而不是CPU?
正在开发诸如OpenCL之类的较新系统,以便我们可以在图形处理器上运行越来越多的代码,这是有道理的,因为我们应该能够尽可能多地利用系统中的功能。 但是,在所有这些新系统中,似乎GPU在各个方面都比CPU更好。因为GPU可以并行计算,所以多核GPU实际上看起来要比多核CPU好得多。您将能够一次进行许多计算,从而真正提高速度。在某些情况下,串行处理仍比并行处理更好,更快和/或更有效吗?
15 optimization  cpu  gpu 

1
为什么Haskell在没有单态性限制的情况下无法避免重复评估?
前几天,我刚学完了youahaskell,并且试图理解Haskell Wiki中描述的“单态限制” 。我想我了解MR如何防止重复评估,但是我看不出为什么用更直接的方法无法避免重复评估。 我想到的具体示例是Wiki使用的示例: f xs = (len,len) where len = genericLength xs 哪里genericLength是类型Num a => [b] -> a。 显然,genericLength xs只需计算一次即可求值(len,len),因为它是具有相同参数的相同函数。我们不需要f知道任何调用即可知道这一点。那么,为什么Haskell不能在不引入MR之类的规则的情况下进行此优化? 那个Wiki页面上的讨论告诉我,它与Num类型类而不是具体类型有关,但是即使这样,在编译时纯函数是否返回相同的值也不应该很明显- -并因此使用相同的Num具体类型-两次给相同的参数?

4
SIMD编程代码库的维护成本
题: 软件行业的共识是,干净,简单的代码对于代码库和拥有它的组织的长期生存至关重要。这些属性导致较低的维护成本,并增加了继续使用代码库的可能性。 但是,SIMD代码与通用应用程序代码不同,我想知道是否有专门针对SIMD代码的简洁代码的相似共识。 我的问题的背景。 我为各种图像处理和分析任务编写了大量的SIMD(单指令,多个数据)代码。最近,我还不得不将少量这些功能从一种体系结构(SSE2)移植到另一种体系结构(ARM NEON)。 该代码是为收缩包装的软件编写的,因此,如果没有不受限制的重新分配权限(例如MATLAB),就不能依赖专有语言。 典型代码结构的示例: 使用OpenCV的矩阵类型(Mat)进行所有内存,缓冲区和生命周期管理。 检查输入参数的大小(尺寸)后,将获得指向每行像素起始地址的指针。 像素计数和来自每个输入矩阵的每一行像素的起始地址都传递给一些低级C ++函数。 这些低级C ++函数使用SIMD内部函数(用于Intel Architecture和ARM NEON),从原始指针地址加载并保存到原始指针地址。 这些低级C ++函数的特征: 唯一一维的(在内存中连续) 不处理内存分配。(每个分配,包括临时性,都由外部代码使用OpenCV工具处理。) 符号的名称长度(内部名称,变量名称等)的范围大约为10-20个字符,这是非常大的。(读起来就像是技术泡沫)。 不鼓励重复使用SIMD变量,因为编译器在正确地解析不是以“单分配”编码方式编写的代码方面存在很多缺陷。(我已经提交了几个编译器错误报告。) SIMD编程的哪些方面会使讨论与一般情况有所不同?或者,为什么SIMD与众不同? 初期开发费用 众所周知,与随便编写的 C ++代码相比,具有良好性能的C ++ SIMD代码的初始开发成本约为10倍至100倍(具有较大的余量)。 正如在性能与可读/清洁代码之间进行选择的答案中所指出的那样?,大多数代码(包括随便编写的代码和SIMD代码)起初既不干净也不快速。 不鼓励对代码性能(在标量代码和SIMD代码中)进行进化改进(因为这被视为一种软件返工),并且没有跟踪成本和收益。 就倾向而言 (例如帕累托原则,又称80-20规则) 即使图像处理仅占软件系统的20%(在代码大小和功能上),图像处理也相对较慢(当以所花费的CPU时间的百分比表示),花费的时间超过80%。 这是由于数据大小的影响:典型的图像大小以兆字节为单位,而非图像数据的典型大小以千字节为单位。 在图像处理代码中,SIMD程序员受过训练,可以通过识别C ++代码中的循环结构来自动识别包含热点的20%代码。因此,从SIMD程序员的角度来看,“重要的代码” 100%是性能瓶颈。 通常在图像处理系统中,存在多个热点,并占用相当比例的时间。例如,可能有5个热点分别占总时间(20%,18%,16%,14%,12%)。为了获得高性能,需要在SIMD中重写所有热点。 这被概括为气球弹出规则:气球不能两次弹出。 假设有一些气球,说5个。抽取它们的唯一方法是将它们逐个弹出。 弹出第一个气球后,剩下的4个气球现在占总执行时间的更高百分比。 为了获得更大的收益,然后必须弹出另一个气球。(这违背了80-20的优化规则:采摘了悬挂率最低的20%的水果后,可以获得良好的经济效果。) 在可读性和维护方面 SIMD代码显然难以阅读。 即使遵循每一项软件工程最佳实践,也是如此,例如命名,封装,const正确性(并使副作用显而易见),函数分解等。 即使对于有经验的SIMD程序员也是如此。 与等效的C ++原型代码相比,最佳SIMD代码非常扭曲(请参阅备注)。 扭曲SIMD代码的方法有很多,但是10种这样的尝试中只有1种会获得可接受的快速结果。 …

11
我怎么知道编译器是否破坏了我的代码?如果是编译器,我该怎么办?
偶尔进行某些级别的优化时,C ++代码将无法工作。可能是编译器进行了优化而破坏了代码,也可能是包含未定义行为的代码,这些行为使编译器可以做任何感觉。 假设我有一些仅在使用更高的优化级别进行编译时会中断的代码。我怎么知道是代码还是编译器,如果是编译器怎么办?

2
蚁群算法
我是一名学生,正在为课程项目开发蚁群模拟器。它的算法(显然)是蚁群算法。我知道算法的形式多种多样,但是所有这些对于我们来说在数学上都过于详细,因此我们采用了一种方法: 一只蚂蚁出生在一个殖民地,必须从源头收集食物以维持这个殖民地。 所有的蚂蚁都是相似的。 蚂蚁移动的区域是1000x1000的网格,因此每个网格点都可作为蚂蚁占据的有效点。现在,我遇到的所有算法都涉及分别处理顶点和边缘,但是由于我们将蚂蚁的移动限制在四个方向(上,下,左,右),所以我认为将信息素放在何处都没有关系。 上述网格点存储信息素。 蚂蚁仅在携带食物时才会滴下信息素。 对于处于位置(i,j)的蚂蚁,它通过简单的概率公式考虑到其四个相邻节点上的信息素量来决定下一步移动的位置,即,通过(特定相邻节点的信息素数量)/(4个相邻节点的信息素数量之和)。 一只蚂蚁不能回到原来的位置。它只有在有食物的地方或在其殖民地时才能这样做。 现在,我担心的是(以及程序中实际发生的事情)是,当一只蚂蚁FIRST到达有食物并捡起它的位置时,通过我们的算法起作用,它可以移动到任何地方!这是因为它只会留下一条信息素踪迹,一旦它有了食物而不是之前,并且因为它是第一只蚂蚁,就不存在信息踪迹了。 如果蚂蚁可以移动到任何地方,到达食物源后的蚂蚁也往往会跟随它前进。即使它没有移回殖民地,也是如此。这违反了整个算法的目的。 所以我的问题是 上述关注有效吗?如果没有,那为什么呢?如果是,那该如何处理呢? 我们是否需要对算法的基本理解进行一些更改才能使其真正起作用? 在这种情况下,像我这样的新手可能还会错过其他一些微妙但重要的事情吗?

4
优化CPU缓存(在C中)时重要的是什么?
阅读这两个问题,我发现了解CPU缓存行为在处理内存中的大量数据时可能很重要。我想了解缓存的工作方式,以便将其他工具添加到优化工具箱中。 关于CPU缓存工作方式的核心点是什么,以便我可以编写明智地使用它的代码?相关地,是否有一种方法可以对代码进行概要分析,以查看缓存使用不当是否会减慢速度?

3
如果大型公司总是违反网络最佳实践,那么它们是如此重要吗?
通常,有许多规则和最佳做法可帮助优化网站,吸引新客户,并通常在使用户体验快速,流畅和令人愉悦的同时(有时)减少服务器负载。 而且,通常,大型公司不会费心使用这些最佳做法。在最大的网站上,除了少数公司(例如Google),我们可以看到: 表格布局,而不是最小化的JavaScript,应该没有CSS精灵,几个CSS文件,侵入性的JavaScript,即使在那些简单易行的情况下,在中调用JavaScript文件<head/>等。 无意义的错误,烦人的弹出窗口,需要填写大量字段的注册表,寄存器上的UX问题¹,愚蠢的问题和无法使用网站²的情况,网站关键部分上令人困惑的情况³,多次重定向,慢速页面等。 一方面,由于它们的成功部分或完全依赖于网站,这些公司为开发,优化和托管其网站付出了巨额资金;另一方面,他们不断违反最佳做法,而拥护这些最佳做法的人们则解释说,遵循这些最佳做法有助于实现更好的用户体验和更快的网站,而占用的环境更少(在托管于数千台服务器上的网站上不可忽略) 。 在这种情况下,提出以下要求是合乎逻辑的: 如果真正成功的大公司的网站和称职的员工确实有很多钱,并且那些对网站优化的关注不断违反这些最佳实践,那么这些最佳实践是真的吗? 或者,换句话说,如果这些最佳实践如此重要,并且对优化网站有很大帮助,那么为什么这些公司不关心它们? 让我们以Dell.com为例。我敢肯定,他们会聘请最好的人来创建他们的主页。他们的主页使用表格布局。这是否意味着那些说表格布局不好的人错了?这是否意味着戴尔聘用的最好的人才不称职? ¹第一个示例:eBay使得在注册时无法在两个字段中都粘贴您的邮件地址,从而使注册表格的使用时间更长,除了惹恼用户之外,没有其他理由;最佳做法是禁止复制,但允许粘贴。第二个示例:Microsoft Live将密码的长度限制为16个字符,没有任何明显的原因。 ²例如,当您很长一段时间没有去亚马逊时,它说密码无效,然后要恢复密码,询问您上次交易的信息,如果您已经使用过该帐户,则该帐户将不可用从未与该帐户进行过任何交易。 ³例如,Dell使得无法订购没有任何硬盘的机架服务器,而如果您已经拥有要重用的硬盘,这将是完全有效的。 optimization这种优化包括局部刷新以更快地发送最重要的内容,研究等待页面加载的时间与使用网站的人数之间的关系等 。⁵对于戴尔,微软等公司。 ⁶至于eBay或其他基于网络的公司。

6
为什么编译器不内联所有内容?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 5年前关闭。 有时,编译器会内联函数调用。这意味着它们将被调用函数的代码移到调用函数中。这使事情变得更快一些,因为不需要在调用堆栈中上下移动内容。 所以我的问题是,为什么编译器不内联所有内容?我认为这将使可执行文件明显更快。 我能想到的唯一原因是可执行文件大得多,但是如今拥有数百GB内存真的重要吗?改进的性能值得吗? 还有其他原因导致编译器不仅仅内联所有函数调用吗?

1
通过微前端向下发送冗余代码
我对微前端的理解是,他们解决的关键问题是帮助企业拥有多个可能组成不同的团队,研究将用于组成大型Web应用程序的单个组件/小型应用程序。 这里要解决的关键问题是多个团队独立工作的能力,并且仍然能够构建大型复合材料。问题不在于为最终用户提供精简的发行包。这种理解正确吗? 的确,如果我们有多个用于组成大型Web应用程序的小型应用程序,则有可能会有多个小型应用程序将相同的Javascript库(例如Lodash)作为最终用户的一部分传送给最终用户的浏览器。各个供应商捆绑包是否导致一定数量的重复/冗余代码被发送给用户? 在设计前端应用程序时,这不是我们应该担心的问题吗?

4
防止代码库变慢的方法
我们正在开发中等大小的C ++代码库(10Mloc),通过我们的优化工作,它逐渐变得越来越慢。 该代码库是一组库,我们将它们组合起来以使其起作用。当开发出这些库如何通信的通用框架时,便会着重于性能,后来,当添加更多部分时,通用框架并没有太大变化。在需要时以及随着我们的硬件发展而进行了优化。这使得昂贵的早期决定只有在很久以后才显现出来。现在我们处于进一步优化的代价更高的位置,因为它们需要重写代码库的大部分内容。我们发现自己逼近了不希望有的局部最小值,因为我们知道原则上代码应该能够更快地运行。 是否有任何成功的方法论可以帮助您确定将代码库的发展转向全球最佳执行解决方案的过程,而这些过程又不容易被轻松的优化机会所混淆? 编辑 要回答我们当前如何配置的问题: 实际上,只有两种不同的情况可以使用此代码,这两种情况都令人尴尬地是并行的。使用大量输入的平均值和更详细的运行时间(指令成本,分支错误预测和缓存问题)对挂钟时间进行平均,即可进行性能分析。由于我们仅在极其同类的计算机(由数千个相同的计算机组成的集群)上运行,因此效果很好。由于通常我们大部分时间都在使所有机器繁忙,因此运行速度更快,这意味着我们可以查看其他新内容。问题当然是,当出现新的输入变化时,由于我们删除了其他用例中最明显的微效率问题,因此它们可能会受到后来者的惩罚,从而可能缩小“最佳运行”方案的数量。
11 c++  optimization 

4
如何记录和教导其他人“无法识别的优化”计算密集型代码?
有时候,有1%的代码需要足够的计算强度,因此需要最重的底层优化。通常,示例是视频处理,图像处理和各种信号处理。 我们的目标是记录文档并教授优化技术,以使代码不会变得难以维护,并易于被新的开发人员删除。(*) (*)尽管在某些不可预见的未来CPU中特定优化可能完全没有用,所以无论如何都会删除代码。 考虑到软件产品(商业或开放源代码)通过拥有最快的代码并利用最新的CPU架构来保持竞争优势,软件作者通常需要调整其代码以使其运行得更快,同时为特定产品获得相同的输出。任务,允许少量舍入错误。 通常,软件编写者可以保留函数的多个版本,作为每次进行的优化/算法重写的文档。一个人如何使这些版本可供其他人学习其优化技术? 有关: 干净可读的代码与快速难以读取的代码。什么时候越界?

3
电梯算法及其实现
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,以使它成为软件工程堆栈交换的主题。 5年前关闭。 我想知道(真实的)电梯如何工作。但是到目前为止,我找不到关于它们使用的算法的太多材料,也找不到用于仿真的软件(如果有)。有人可以给我参考吗?

5
在C ++中优化冗余字符串分配
我有一个相当复杂的C ++组件,其性能已成为问题。分析表明,大多数执行时间只是花在为std::strings 分配内存上。 我知道这些字符串之间有很多冗余。少数值非常频繁地重复,但也有很多唯一值。字符串通常很短。 我现在只是在考虑以某种方式重用那些频繁的分配是否有意义。代替1000个指向1000个不同的“ foobar”值的指针,我可以有1000个指向一个“ foobar”值的指针。这样可以提高内存效率,这是一个不错的选择,但是我在这里最担心的是延迟。 我猜一个选择是维护某种已经分配了值的注册表,但是是否有可能使注册表查找比冗余内存分配更快?这是可行的方法吗?

5
您是否应该尽量减少创建许多小对象?
在编写经常创建许多(1000个)小对象的东西时,您是否应尝试将其最小化以提高性能?特别是如果您不知道它将在低端台式机到高端台式机甚至是移动设备上运行的系统。对于移动设备,我听说创建很多对象会严重影响性能,尽管我不知道那是多么真实。 我有一个例子很好地说明了这个想法。例如,在图形程序中,存在一种理想地用于所有绘图的方法drawPixel(Point)。可能会创建1000点,并且可能会经常重复,例如在游戏中每秒可能会被调用60次以上。或者,drawPixel(int x, int y)可用于最小化许多Point对象的创建。 在面向对象的设计中,我认为首选使用Point。但是,使用基本类型可以提高性能。在大多数情况下,性能提升可以忽略不计,但是我不确定移动设备或旧机器之类的东西。这样做会提高性能,应该考虑吗?

7
何时开始考虑可伸缩性?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 我遇到了一个有趣但又可怕的问题。我将要启动一个新的(iPhone)应用程序。这是在我自己的自定义后端上运行的基于回合的多人游戏。但是我怕发射。 由于某种原因,我认为它可能会变得很大,并且它的流行将杀死我可怜的孤独的单服务器+ MySQL数据库。 一方面,我在想如果它正在增长,那么我最好做好准备,并拥有可扩展的基础架构。 另一方面,我只是想将其发布到世界上,看看会发生什么。 我经常读诸如“过早的优化是万恶之源”之类的文章,或者有人说您应该立即使用手头的工具来构建杀手级游戏,而后再担心诸如可扩展性之类的问题。 我很想听听专家或有经验的人对此的一些看法。谢谢!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.