这个网站上已经存在很多性能问题,但是我发现几乎所有这些都是特定于问题且相当狭窄的问题.几乎所有人都重复这些建议,以避免过早优化.
我们假设:
我在这里寻找的是在一个关键算法中挤出最后几个百分点的策略和技巧,除此之外别无他法.
理想情况下,尝试使答案语言不可知,并在适用的情况下指出建议策略的任何缺点.
我将使用我自己的初步建议添加回复,并期待Stack Overflow社区可以想到的任何其他内容.
我不时会读到Fortran是或者可以比C更快进行繁重的计算.这是真的吗?我必须承认我几乎不知道Fortran,但到目前为止我见过的Fortran代码并没有表明该语言具有C所没有的功能.
如果是真的,请告诉我原因.请不要告诉我哪些语言或库对数字运算有好处,我不打算写一个app或lib来做那个,我只是很好奇.
Note: I'd appreciate more of a guide to how to approach and come up with these kinds of solutions rather than the solution itself.
I have a very performance-critical function in my system showing up as a number one profiling hotspot in specific contexts. It's in the middle of a k-means iteration (already multi-threaded using a parallel for processing sub-ranges of points in each worker thread).
ClusterPoint& pt = points[j];
pt.min_index = -1;
pt.min_dist = numeric_limits<float>::max();
for (int i=0; i …Run Code Online (Sandbox Code Playgroud) 我仍然是一名新手程序员,我知道过早的优化很糟糕,但我也知道复制大量的东西也很糟糕.
我已经阅读了复制省略和它的同义词,但维基百科上的例子让我觉得复制省略只有在要完全构建的同时返回要返回的对象时才会发生.
那些像矢量这样的对象呢?当用作返回值时,它通常只在填充某些东西时才有意义.毕竟,可以手动实例化空矢量.
那么,它是否也适用于这样的情况?
简洁的风格:
vector<foo> bar(string baz)
{
vector<foo> out;
for (each letter in baz)
out.push_back(someTable[letter]);
return out;
}
int main()
{
vector<foo> oof = bar("Hello World");
}
Run Code Online (Sandbox Code Playgroud)
我使用bar(矢量和输出,字符串文本)没有真正的麻烦,但上面的方式看起来更好,美观,并且意图.
在查看有关优化的一些问题时,对于最有效地使用优化器的编码实践问题,这个接受的答案激起了我的好奇心.断言是局部变量应该用于函数中的计算,而不是输出参数.有人建议这将允许编译器进行额外的优化,否则不可能.
因此,为示例Foo类编写一段简单的代码并使用g ++ v4.4和-O2编译代码片段会产生一些汇编器输出(使用-S).汇编程序列表的部分只包含如下所示的循环部分.在检查输出时,两个循环似乎几乎相同,只有一个地址不同.该地址是第一个示例的输出参数或第二个示例的局部变量的指针.
无论是否使用局部变量,实际效果似乎都没有变化.所以问题分为3部分:
a)即使给出提示,GCC也没有进行额外的优化;
b)GCC 在两种情况下都成功优化,但不应该;
c)GCC是否在两种情况下都成功优化,并且正在生成C++标准定义的兼容输出?
这是未经优化的功能:
void DoSomething(const Foo& foo1, const Foo* foo2, int numFoo, Foo& barOut)
{
for (int i=0; i<numFoo, i++)
{
barOut.munge(foo1, foo2[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
和相应的组装:
.L3:
movl (%esi), %eax
addl $1, %ebx
addl $4, %esi
movl %eax, 8(%esp)
movl (%edi), %eax
movl %eax, 4(%esp)
movl 20(%ebp), %eax ; Note address is that of the output argument
movl %eax, (%esp)
call _ZN3Foo5mungeES_S_
cmpl %ebx, 16(%ebp) …Run Code Online (Sandbox Code Playgroud) 我正在寻找程序员在C中可以做什么,它可以确定生成的目标文件的性能和/或大小.
例如,
1.将简单的get/set函数声明为inline可能会提高性能(以更大的占用空间为代价)
2.对于不使用循环变量本身值的循环,倒计时到零而不是计数到一定的价值等
看起来编译器现在已经发展到了一个"简单"技巧(如上面的两点)根本不需要的水平.编译期间适当的选项无论如何都可以完成工作.哎呀,我还看到了关于编译器如何处理递归的帖子 - 这非常有趣!那么我们还要做什么呢?:)
我的具体环境是:GCC 4.3.3重新针对ARM架构(v4).但是对其他编译器/处理器的响应也是受欢迎的,并且将被扼杀.
PS:我的这种做法违背了通常的"代码优先!然后基准,最后优化"的方法.
编辑:就像它发生的那样,在发布问题之后我发现了一个类似的帖子:我们还应该优化"在小"吗?