小编mil*_*anw的帖子

启用C++ 11时std :: vector performance regression

当我启用C++ 11时,我在一个小的C++片段中发现了一个有趣的性能回归:

#include <vector>

struct Item
{
  int a;
  int b;
};

int main()
{
  const std::size_t num_items = 10000000;
  std::vector<Item> container;
  container.reserve(num_items);
  for (std::size_t i = 0; i < num_items; ++i) {
    container.push_back(Item());
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用g ++(GCC)4.8.2 20131219(预发行版)和C++ 03,我得到:

milian:/tmp$ g++ -O3 main.cpp && perf stat -r 10 ./a.out

Performance counter stats for './a.out' (10 runs):

        35.206824 task-clock                #    0.988 CPUs utilized            ( +-  1.23% )
                4 context-switches          #    0.116 K/sec                    ( +-  4.38% )
                0 cpu-migrations …
Run Code Online (Sandbox Code Playgroud)

c++ performance gcc vector c++11

235
推荐指数
1
解决办法
6548
查看次数

linux perf:如何解读和查找热点

我今天尝试了linux的perf实用程序,但在解释其结果方面遇到了麻烦.我已经习惯了valgrind的callgrind,这当然是一种完全不同于基于采样的perf方法的方法.

我做了什么:

perf record -g -p $(pidof someapp)
perf report -g -n
Run Code Online (Sandbox Code Playgroud)

现在我看到这样的事情:

+     16.92%  kdevelop  libsqlite3.so.0.8.6               [.] 0x3fe57                                                                                                              ?
+     10.61%  kdevelop  libQtGui.so.4.7.3                 [.] 0x81e344                                                                                                             ?
+      7.09%  kdevelop  libc-2.14.so                      [.] 0x85804                                                                                                              ?
+      4.96%  kdevelop  libQtGui.so.4.7.3                 [.] 0x265b69                                                                                                             ?
+      3.50%  kdevelop  libQtCore.so.4.7.3                [.] 0x18608d                                                                                                             ?
+      2.68%  kdevelop  libc-2.14.so                      [.] memcpy                                                                                                               ?
+      1.15%  kdevelop  [kernel.kallsyms]                 [k] copy_user_generic_string                                                                                             ?
+      0.90%  kdevelop  libQtGui.so.4.7.3                 [.] QTransform::translate(double, double)                                                                                ?
+      0.88%  kdevelop  libc-2.14.so                      [.] __libc_malloc                                                                                                        ?
+ …

c++ linux performance profiling perf

43
推荐指数
5
解决办法
3万
查看次数

如何忽略`git stash -p`中添加的帅哥

想象一下这种情况:

# edit two files
git add -p // add hunks from one file
Run Code Online (Sandbox Code Playgroud)

现在,当你跑步时git stash -p,它会再次询问你是否想藏匿你刚才选择的帅哥git add -p.有没有办法配置git默认忽略这些已经添加的帅哥?大多数时候,我不想隐藏我已添加的东西.

git git-stash

16
推荐指数
2
解决办法
440
查看次数

c ++ 0x:解决函数定义后跟空声明和简单声明之间的歧义

我在c ++ 0x规范中明显含糊不清时遇到了问题,另请参阅:http://www.nongnu.org/hcb/

假设我们有代码

void foo() {};
Run Code Online (Sandbox Code Playgroud)

我个人将代码解释为a function-definition后跟a empty-declaration.但是,看一下语法规范,我会说这可以很容易地被解释为a simple-declaration,这是...的一部分,block-declaration因此在declaration...... 的列表中提到的更快.

以下是我如何将其解析为简单声明的解释:

void foo() {};"
Run Code Online (Sandbox Code Playgroud)

- >简单声明

void
Run Code Online (Sandbox Code Playgroud)

- > decl-specifier-seq - > decl-specifier - > type-specifier - > trailing-type-specifier - > simple-type-specifier

foo() {}
Run Code Online (Sandbox Code Playgroud)

- > init declarator-list - > init-declarator

foo()
Run Code Online (Sandbox Code Playgroud)

- > declarator - > ptr-declarator - > noptr-declarator

foo
Run Code Online (Sandbox Code Playgroud)

- > declarator-id - > ...

()
Run Code Online (Sandbox Code Playgroud)

- >参数和限定符

{} 
Run Code Online (Sandbox Code Playgroud)

- > initializer - > braced-init-list …

c++ parsing specifications c++11

15
推荐指数
1
解决办法
475
查看次数

使用Visual Studio Compiler分析内联C++函数

当大量代码被编译器内联时,我怎样才能理解Windows上的C++分析数据?即我当然想要测量实际运行的代码,因此根据定义,我将测量代码的优化构建.但似乎我尝试实际设法解决内联函数的工具都没有.

我已经尝试过Visual Studio 2017 Professional和VTune 2018中的采样分析器.我试过启用/Zo,但它似乎没有任何影响.

我发现以下资源似乎表明只有Visual Studio Ultimate或Premium支持内联框架信息 - 这仍然适用于Visual Studio 2017吗?https://social.msdn.microsoft.com/Forums/en-US/9df15363-5aae-4f0b-a5ad-dd9939917d4c/which-functions-arent-pgo-optimized-using-profile-data?forum=vsdebug

这是一个示例代码:

#include <cmath>
#include <random>
#include <iostream>

inline double burn()
{
    std::uniform_real_distribution<double> uniform(-1E5, 1E5);
    std::default_random_engine engine;
    double s = 0;
    for (int i = 0; i < 100000000; ++i) {
        s += uniform(engine);
    }
    return s;
}

int main()
{
    std::cout << "random sum: " << burn() << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在发布模式下使用Visual Studio编译它.或者在命令行上,尝试cl /O2 /Zi /Zo /EHsc main.cpp.然后尝试使用Visual Studio中的CPU Sampling Profiler对其进行配置.你最多会看到这样的事情: …

c++ profiling inline visual-studio visual-studio-debugging

15
推荐指数
1
解决办法
1452
查看次数

重载运行进程的符号(LD_PRELOAD附件)

我正在研究Linux的堆分析器,称为heaptrack.目前,我依赖于LD_PRELOAD重载各种(解)分配函数,这非常有效.

现在我想扩展该工具以允许运行时附加到现有进程,该进程是在没有LD_PRELOAD我的工具的情况下启动的.我可以dlopen通过GDB很好地使用我的库,但是这不会覆盖malloc等等.我认为,这是因为此时链接器已经解决了已经运行的进程的位置相关代码 - 正确吗?

那么我该怎么办才能超载malloc和朋友呢?

我不熟悉汇编代码.从我到目前为止所读到的,我想我将以某种方式必须修补malloc和其他功能,以便他们首先回调我的跟踪功能,然后继续他们的实际实现?那是对的吗?我怎么做?

我希望有现有的工具,或者我可以利用GDB/ptrace.

c linux gdb runtime dynamic-linking

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

如何找到全局静态初始化

我刚刚阅读了这篇出色的文章:http : //neugierig.org/software/chromium/notes/2011/08/static-initializers.html 然后我尝试了:https : //gcc.gnu.org/onlinedocs/gccint/Initialization .html

不过,它关于查找初始化程序的内容对我不起作用。该.ctors部分不可用,但我可以找到.init_array(另请参阅Can't find .dtors and .ctors in binary)。但是我如何解释输出?我的意思是,总结页面的大小也可以由size命令及其.bss列处理 - 或者我错过了什么?

此外,nm不报告任何*_GLOBAL__I_*符号,仅报告*_GLOBAL__N_*函数和 - 更有趣的 -_GLOBAL__sub_I_somefile.cpp条目。后者可能表示具有全局初始化的文件。但是我能以某种方式获得正在运行的构造函数列表吗?理想情况下,一个工具会给我一个列表

Foo::Foo in file1.cpp:12
Bar::Bar in file2.cpp:45
...
Run Code Online (Sandbox Code Playgroud)

(假设我有可用的调试符号)。有这样的工具吗?如果不是,那怎么写呢?该.init_array部分是否包含指向可以通过一些 DWARF 魔法转换为上述代码的指针?

c++ linux initialization global-variables binutils

6
推荐指数
1
解决办法
3198
查看次数

使用键值数据库作为具有持久索引的集合

因为下面有点长:这是tl; dr; version:快速键值查找是否存在现有键/值最佳实践,类似于具有持久索引的基于哈希的集合?

我对键值数据库的世界感兴趣,到目前为止还没有弄清楚如何有效地实现以下用例:

假设我们想要序列化一些数据,并通过持久的唯一整数索引在其他地方引用它们.例如:Key = unsigned int,Value = MyData.

数据库应具有快速键查找并确保MyData是唯一的.

现在,当我向数据库插入一个新值时,我可以为它分配一个新的索引键,例如数据库的当前大小,或者为了防止在删除项目后发生冲突,我可以在外部保留一些计数器.

但是,我如何确保不将相同的MyData值插入数据库?到目前为止,它看起来好像这对于键值数据库来说无法有效实现 - 这是正确的吗?即我希望遍历整个数据库只是为了确保MyData的价值并不在那里已经...

那么实施这个的最佳实践是什么?

对于背景:我在KDevelop上工作,我们使用上面的代码分析缓存.我们实际上有一个上述用例1的自定义实现.如果您对内部感兴趣,请搜索Bucket和ItemRepository,并参阅2以了解ItemRepository的示例用法.

但你可能会同意,这段代码很难理解,因而难以维护.我想将其性能与可能导致更简单代码的替代解决方案进行比较 - 但前提是它不会导致严重的性能损失.考虑到围绕OpenLDAP MDB,Kyoto Cabinet和LevelDB等键值存储性能的炒作,这是我想要开始的地方.

我们在KDevelop中所拥有的 - 据我所知 - 基本上是一种混合磁盘/内存中的哈希映射,它会定期保存到磁盘上(当然,在崩溃的情况下会导致严重的数据损坏等). ).项目基于它们的散列值存储在一个位置,当然,只要散列函数很快,它们也允许相对快速的值查找.增加的扭曲是您还获得某种持久性数据库索引,可用于非常有效地查找项目.

所以 - 长话短说 - 如何用一个关键/价值数据库如LevelDB,Kyoto Cabinet,OpenLDAP MDB来做到这一点 - 你说出来了吗?

indexing key-value openldap kyotocabinet leveldb

5
推荐指数
1
解决办法
1093
查看次数

将 std::unique 与减少步骤相结合的算法?

有人能想出一个干净(和快速)的解决方案来解决以下问题:

  • 我有一系列条目,基本上包含一个键和一个值,比如
struct Value {
    int index = 0;
    int cost = 0;
}
Run Code Online (Sandbox Code Playgroud)
  • 我现在想合并条目,这样每个键只包含一次,但值应该组合 - 即每个index应该只包含在序列中一次,并且cost应该累积每个重复索引。

我想出的基本解决方案对序列进行排序,当在BinaryPredicate传递给中检测到相等的条目时std::sortcost将相加到lhs. 然后将的成本rhs设置为 0。然后跟随一个remove_if删除 0 成本值。请参见此处的示例:

#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iostream>

struct Value
{
    int index = 0;
    int cost = 0;
};

// generate a bunch of random values in a vector
// values will have indices in range [0..10]
std::vector<Value> generator()
{
    std::vector<Value> …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm stl

4
推荐指数
1
解决办法
306
查看次数