标签: optimization

C++:将一个操作数保存在寄存器中的神秘速度非常快

我一直试图通过计算一个使用以下代码对数组元素进行扩展和求和的例程来了解在L1缓存与内存中使用数组的影响(我知道我应该将结果缩放为' a'在最后;关键是在循环中同时进行乘法和加法 - 到目前为止,编译器还没有想出要将'a'分解出来):

double sum(double a,double* X,int size)
{
    double total = 0.0;
    for(int i = 0;  i < size; ++i)
    {
        total += a*X[i];
    }
    return total;
}

#define KB 1024
int main()
{
    //Approximately half the L1 cache size of my machine
    int operand_size = (32*KB)/(sizeof(double)*2);
    printf("Operand size: %d\n", operand_size);
    double* X = new double[operand_size];
    fill(X,operand_size);

    double seconds = timer();
    double result;
    int n_iterations = 100000;
    for(int i = 0; i < n_iterations; ++i)
    {
        result = …
Run Code Online (Sandbox Code Playgroud)

c c++ optimization performance assembly

69
推荐指数
3
解决办法
3938
查看次数

C++优化器重新排序对clock()的调用是否合法?

C++编程语言第4版,第225页读取:只要结果与简单执行顺序的结果相同,编译器就可以重新排序代码以提高性能.一些编译器,例如发布模式下的Visual C++,将重新排序此代码:

#include <time.h>
...
auto t0 = clock();
auto r  = veryLongComputation();
auto t1 = clock();

std::cout << r << "  time: " << t1-t0 << endl;
Run Code Online (Sandbox Code Playgroud)

进入这种形式:

auto t0 = clock();
auto t1 = clock();
auto r  = veryLongComputation();

std::cout << r << "  time: " << t1-t0 << endl;
Run Code Online (Sandbox Code Playgroud)

这保证了与原始代码不同的结果(零与大于零的时间报告).有关详细示例,请参阅我的其他问题 这种行为是否符合C++标准?

c++ optimization clock

69
推荐指数
3
解决办法
3741
查看次数

PostgreSQL临时表

我需要执行250万次查询.此查询生成我需要的一些行,AVG(column)然后使用它AVG来从低于平均值的所有值中过滤表.然后我需要将INSERT这些过滤结果放入表格中.

以合理的效率执行此类操作的唯一方法似乎是TEMPORARY TABLE为每个query-postmaster python-thread 创建一个.我只是希望这些TEMPORARY TABLEs不会被持久化到硬盘驱动器(根本)并且将保留在内存(RAM)中,当然,除非它们没有工作内存.

我想知道TEMPORARY TABLE是否会引发磁盘写入(这会干扰INSERTS,即整个进程缓慢)

postgresql optimization performance temp-tables

68
推荐指数
2
解决办法
8万
查看次数

如果我将Objective-C用于低级代码,我的iPhone应用程序会受到性能影响吗?

在iPhone或其他便携式硬件上编程CPU密集型或GPU密集型应用程序时,您必须做出明智的算法决策,以使您的代码更快.

但是,如果你使用的语言表现得比另一种语言差,那么即使是很好的算法选择也会很慢.

有没有比较Objective-C和C++的硬数据,特别是在iPhone上,但可能只是在Mac桌面上,以获得各种类似语言方面的表现?我非常熟悉这篇比较C和Objective-C的文章,但这是一个比较两种面向对象语言的更大问题.

例如,C++ vtable查找是否真的比Obj-C消息快?多快了?线程,多态,排序等.在我开始构建具有重复对象模型和各种测试代码的项目之前,我想知道是否有人已经完成了这个以及结果在哪里.这种类型的测试和比较本身就是一个项目,可能需要相当长的时间.也许这不是一个项目,但可以比较两个而且只有输出.

我正在寻找硬数据,而不是传福音.像许多人一样,我喜欢和讨厌两种语言,原因各种各样.此外,如果有人在那里积极地追求同样的事情,我会有兴趣投入一些代码来查看最终结果,我相信其他人也会帮忙.我的猜测是他们都有优点和缺点,我的目标是准确找出它们是什么,以便在现实世界的场景中避免/利用它们.

c++ iphone optimization performance objective-c

68
推荐指数
4
解决办法
5万
查看次数

在C中使用restrict关键字的规则?

我试图了解何时何时不在restrictC中使用关键字以及在什么情况下它提供了实实在在的好处.

在阅读" 揭秘限制关键字 "(提供一些关于使用的经验法则)之后,我得到的印象是,当函数通过指针时,它必须考虑指向的数据可能重叠的可能性(别名)将任何其他参数传递给函数.给定一个功能:

foo(int *a, int *b, int *c, int n) {
    for (int i = 0; i<n; ++i) {
        b[i] = b[i] + c[i];
        a[i] = a[i] + b[i] * c[i];
    } 
}
Run Code Online (Sandbox Code Playgroud)

编译器必须c在第二个表达式中重新加载,因为可能bc指向相同的位置.ba出于同样的原因加载之前,它还必须等待存储.然后它必须等待a存储并且必须重新加载b并且c在下一个循环的开始.如果你这样调用函数:

int a[N];
foo(a, a, a, N);
Run Code Online (Sandbox Code Playgroud)

然后你就可以看到为什么编译器必须这样做了.使用restrict有效地告诉编译器你永远不会这样做,这样它就可以在存储之前丢弃冗余负载c和负载.ab

在另一篇SO帖子中,Nils Pipenbrinck提供了这个场景的工作示例,展示了性能优势.

到目前为止,我已经收集到了一个好主意,使用restrict指针传递给不会内联的函数.显然,如果代码是内联的,编译器可以发现指针不重叠.

现在,这里的事情开始让我变得模糊.

在Ulrich Drepper的论文中," 每个程序员应该了解内存 ",他发表声明称,"除非使用限制,所有指针访问都是混淆的潜在来源",并且他给出了一个子矩阵矩阵的特定代码示例.用途restrict.

但是,当我编写他的示例代码时,无论有没有, …

c memory optimization

68
推荐指数
3
解决办法
2万
查看次数

编译器优化会引入错误吗?

今天我和我的一个朋友进行了讨论,我们就"编译器优化"进行了几个小时的讨论.

我辩护说,有时,编译器优化可能会引入错误或至少是不良行为.

我的朋友完全不同意,他说"编译器是由聪明人构建并做聪明的东西",因此永远不会出错.

他根本没有说服我,但我不得不承认我缺乏现实生活中的例子来强化我的观点.

谁在这?如果是的话,您是否有任何现实生活中的例子,编译器优化会在生成的软件中产生错误?如果我错了,我应该停止编程并学习钓鱼吗?

compiler-construction optimization compiler-optimization

68
推荐指数
10
解决办法
2万
查看次数

foldl是尾递归的,那么foldr如何比foldl运行得更快呢?

我想测试foldl vs foldr.从我所看到的,你应该使用foldl over foldr,因为尾部递归优化.

这是有道理的.但是,运行此测试后,我很困惑:

foldr(使用时间命令时需要0.057秒):

a::a -> [a] -> [a]
a x = ([x] ++ )

main = putStrLn(show ( sum (foldr a [] [0.. 100000])))
Run Code Online (Sandbox Code Playgroud)

foldl(使用time命令时需要0.089s):

b::[b] -> b -> [b]
b xs = ( ++ xs). (\y->[y])

main = putStrLn(show ( sum (foldl b [] [0.. 100000])))
Run Code Online (Sandbox Code Playgroud)

很明显,这个例子很简单,但我很困惑为什么foldr击败foldl.这不应该是foldl获胜的明显案例吗?

optimization haskell tail-recursion combinators fold

68
推荐指数
4
解决办法
2万
查看次数

为什么喜欢在C++中签名无符号?

我想更好地了解为什么选择int结束unsigned

就个人而言,除非有正当理由,否则我从未喜欢过签名的价值观.例如,数组中的项目数,或字符串的长度,或内存块的大小等,因此这些事情通常不可能是负面的.这样的价值没有任何意义.为什么喜欢int在所有这些情况下误导?

我问这个问题是因为Bjarne Stroustrup和Chandler Carruth都给出了建议,而int不是unsigned 在这里(约12:30').

我可以看到使用intover shortlong- 的参数int是目标机器架构的"最自然"的数据宽度.

但签署无条件总是让我生气.在典型的现代CPU架构上,签名值是否真的更快?是什么让他们更好?

c++ optimization

68
推荐指数
8
解决办法
6896
查看次数

在'perf stat'结果中,什么是停滞 - 循环 - 前端和停滞 - 循环 - 后端?

有人知道在perf stat结果中stalled -cycles-frontendstalled-cycles-backend是什么意思吗?我在互联网上搜索但没有找到答案.谢谢

$ sudo perf stat ls                     

Performance counter stats for 'ls':

      0.602144 task-clock                #    0.762 CPUs utilized          
             0 context-switches          #    0.000 K/sec                  
             0 CPU-migrations            #    0.000 K/sec                  
           236 page-faults               #    0.392 M/sec                  
        768956 cycles                    #    1.277 GHz                    
        962999 stalled-cycles-frontend   #  125.23% frontend cycles idle   
        634360 stalled-cycles-backend    #   82.50% backend  cycles idle
        890060 instructions              #    1.16  insns per cycle        
                                         #    1.08  stalled cycles per insn
        179378 branches                  #  297.899 M/sec                  
          9362 branch-misses             #    5.22% of all …
Run Code Online (Sandbox Code Playgroud)

linux optimization performance cpu-architecture computer-architecture

68
推荐指数
4
解决办法
2万
查看次数

我可以从Dalvik和Android工具链中得到什么样的优化?

我正在开发一个高性能的Android应用程序(游戏),尽管我首先尝试编写可读性代码,但我想在脑海中留下一个关于幕后发生的事情的图片.使用C++,我已经对编译器将为我做什么和不做什么做了很好的直觉.我正在尝试为Java/Android做同样的事情.

因此这个问题.我在网上找不到这个话题.Java编译器,Dalvik转换器(dx)和/或JITter(在Android 2.2+上)是否会执行如下优化?

  • 方法内联.在什么条件下?private方法总是可以安全地内联; 这样做会吗?public final方法怎么样?关于其他类对象的方法?static方法?如果编译器可以轻松推导出对象的运行时类型,该怎么办?我要声明的方法finalstatic在可能的情况?

  • 常见的子表达式消除.例如,如果我访问someObject.someField两次,查找只会进行一次吗?如果它是对吸气剂的召唤怎么办?如果我使用一些算术表达式两次会怎么样 它只会被评估一次吗?如果我使用某些表达式的结果,我知道它的值不会改变,作为for循环的上限,该怎么办?

  • 检查数组查找的边界.工具链是否会在某些条件下消除这种情况,例如原型for循环?

  • 价值内联.访问一些public static final int总是内联?即使他们在另一个班级?即使他们在另一个包裹?

  • 分支预测.这甚至有多大问题?是否会在典型的Android设备上大幅提升性能?

  • 简单算术.将someInt * 2被取代someInt << 1

诸如此类......

java optimization android dalvik

67
推荐指数
3
解决办法
7587
查看次数