小编xis*_*xis的帖子

为什么GCC不优化a*a*a*a*a*a到(a*a*a)*(a*a*a)?

我正在对科学应用进行一些数值优化.我注意到的一件事是GCC会pow(a,2)通过编译来优化调用a*a,但调用pow(a,6)没有优化,实际上会调用库函数pow,这会大大降低性能.(相比之下,英特尔C++编译器,可执行文件icc,将消除库调用pow(a,6).)

我很好奇的是,当我更换pow(a,6)a*a*a*a*a*a使用GCC 4.5.1和选项" -O3 -lm -funroll-loops -msse4",它采用5分mulsd的说明:

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
Run Code Online (Sandbox Code Playgroud)

如果我写(a*a*a)*(a*a*a),它会产生

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13
Run Code Online (Sandbox Code Playgroud)

这将乘法指令的数量减少到3. icc具有类似的行为.

为什么编译器不能识别这种优化技巧?

floating-point assembly gcc compiler-optimization fast-math

2083
推荐指数
12
解决办法
20万
查看次数

来自Pylint的Cell-var-from-loop警告

对于以下代码:

for sort_key, order in query_data['sort']:
    results.sort(key=lambda k: get_from_dot_path(k, sort_key),
                 reverse=(order == -1))
Run Code Online (Sandbox Code Playgroud)

Pylint报告错误:

循环中定义的单元变量sort_key(cell-var-from-loop)

任何人都可以暗示这里发生了什么吗?从pylint源代码描述是:

闭包中使用的变量在循环中定义.这将导致所有闭包对闭合变量使用相同的值.

但我不知道这意味着什么.谁能举一个这个问题的例子?

python lambda closures

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

如何在Python中获取"end-of-statement"的lineno

我正在尝试在Python中操作另一个脚本的脚本,要修改的脚本具有如下结构:

class SomethingRecord(Record):
    description = 'This records something'
    author = 'john smith'
Run Code Online (Sandbox Code Playgroud)

ast用来找到description行号,并使用一些代码来更改原始文件,其中新的描述字符串基于行号.到现在为止还挺好.

现在唯一的问题description偶尔是一个多行字符串,例如

    description = ('line 1'
                   'line 2'
                   'line 3')
Run Code Online (Sandbox Code Playgroud)

要么

    description = 'line 1' \
        'line 2' \
        'line 3'
Run Code Online (Sandbox Code Playgroud)

我只有第一行的行号,而不是以下行.所以我的单行替代品会这样做

    description = 'new value'
        'line 2' \
        'line 3'
Run Code Online (Sandbox Code Playgroud)

并且代码被破坏了.我想如果我知道开始和结束的行号/ description赋值行数我可以修复我的代码来处理这种情况.如何使用Python标准库获取此类信息?

python abstract-syntax-tree

39
推荐指数
4
解决办法
2196
查看次数

为什么push_back比先前分配的向量的operator []慢

我刚刚阅读了这篇博客http://lemire.me/blog/archives/2012/06/20/do-not-waste-time-with-stl-vectors/,比较了operator[]作业的性能和push_back预留的内存std::vector,我决定亲自尝试一下 操作很简单:

// for vector
bigarray.reserve(N);

// START TIME TRACK
for(int k = 0; k < N; ++k)
   // for operator[]:
   // bigarray[k] = k;
   // for push_back
   bigarray.push_back(k);
// END TIME TRACK

// do some dummy operations to prevent compiler optimize
long sum = accumulate(begin(bigarray), end(array),0 0);
Run Code Online (Sandbox Code Playgroud)

这是结果:

 ~/t/benchmark> icc 1.cpp -O3 -std=c++11
 ~/t/benchmark> ./a.out
[               1.cpp:   52]     0.789123s  --> C++ new
[               1.cpp:   52]     0.774049s  --> C++ new
[               1.cpp: …
Run Code Online (Sandbox Code Playgroud)

c++ stl vector c++11

34
推荐指数
3
解决办法
1万
查看次数

C++ 11预定义的宏

是否有任何预定义的C++宏,以便代码可以识别标准?

例如,目前大多数编译器将"数组"放入"tr1"文件夹,但对于C++ 11,它将成为STL的一部分.所以目前

#include <tr1/array>
Run Code Online (Sandbox Code Playgroud)

但是c ++ 11

#include <array>
Run Code Online (Sandbox Code Playgroud)

什么是03标准和11标准的预定义宏,我可以使用它#ifdef来识别?

另外,我想C90和C99有宏吗?

Thanksx

c++ c++11

23
推荐指数
3
解决办法
1万
查看次数

当作为右值引用传递时,std :: bind会丢失引用

我有以下代码:

#include <stdio.h>
#include <functional>

template <typename T>
auto callback(T&& func) ->decltype(func())
{
    return func();
}

double test(double& value)
{
    value=value+1.0;
    return value;
}

int main(void)
{
    double t=1.0;
    printf("%f\n",t);
    test(t);
    printf("%f\n",t);
    callback(std::bind(test,t));
    printf("%f\n",t);
}
Run Code Online (Sandbox Code Playgroud)

它输出

1.000000
2.000000
2.000000
Run Code Online (Sandbox Code Playgroud)

这意味着该callback函数获得了副本t而不是引用t.我想知道发生了什么,因为std::bind它应该是完美的转发.

c++ stdbind

21
推荐指数
2
解决办法
6276
查看次数

使用指数退避有什么好处?

当代码等待延迟时间不确定的某种情况时,看起来很多人选择使用指数退避,即等待N秒,检查条件是否满足; 如果没有,等待2N秒,检查条件等.这对于检查恒定/线性增加的时间跨度有什么好处?

linear-programming non-deterministic exponential-backoff retry-logic

15
推荐指数
3
解决办法
3833
查看次数

为什么这需要一个明确的std :: move?

假设我有一个Foo包含std::vectorstd::unique_ptr另一个类的对象构造的类,Bar.

typedef std::unique_ptr<Bar> UniqueBar;

class Foo {
    std::vector<UniqueBar> bars;
public:
    void AddBar(UniqueBar&& bar);
};

void Foo::AddBar(UniqueBar&& bar) {
    bars.push_back(bar);
}
Run Code Online (Sandbox Code Playgroud)

这导致编译错误(在g ++ 4.8.1中)说复制构造函数std::unique_ptr被删除,这是合理的.这里的问题是,因为bar参数已经是一个右值引用,为什么std::unique_ptr要调用复制构造函数而不是它的移动构造函数?

如果我明确地调用std::move,Foo::AddBar那么编译问题就会消失,但我不明白为什么需要这样做.我认为这是多余的.

那么,我错过了什么?

c++ c++11

14
推荐指数
3
解决办法
875
查看次数

std :: fill不会变成POD类型的memset

我期待一个连续容器上的std :: fill,比如说std :: vector,会自动编译成memset的调用.但是,当我尝试以下代码时

#include <vector>
#include <algorithm>
#include <numeric>

using namespace std;

int main()
{
    vector<double> vec(300000);

    fill(vec.begin(),vec.end(),0.0);

    memset(&vec[0],0,vec.size()*sizeof(double));
}
Run Code Online (Sandbox Code Playgroud)

gcc将第一个std :: fill编译成一个简单的循环.但我认为可以通过SSE或其他高级矢量化代码来完成.请给我一个提示.谢谢.

c++

12
推荐指数
2
解决办法
4277
查看次数

在节点中逐行有效地读取文件

我已经知道readline可以用来逐行读取文件,例如

readline
    .createInterface({input: fs.createReadStream('xxx')})
    .on('line', (line) => { apply_regexp_on_line })
    .on('close', () => { report_all_regexps });
Run Code Online (Sandbox Code Playgroud)

但是,这很慢,因为我比较了grepJavaScript regexp 的性能,后者在我测试的regexp上有更好的性能.(见基准)所以我认为我必须责怪节点异步readline.

在我的情况下,我根本不关心异步,我只需要利用JavaScript中的快速正则表达式来处理非常大的日志文件(通常为1-2GB,有时高达10GB).这样做的最佳方式是什么?我唯一关心的是速度.

加分:一些日志文件是gzip压缩的,所以我需要解压缩它们.如果有人可以推荐我一个快速的逐行阅读器,因为纯文本和gzip文本都存在,我将非常感激.

javascript node.js

12
推荐指数
1
解决办法
1820
查看次数