首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我能“强制”Cachegrind分析一个操作(或行)吗?

我能“强制”Cachegrind分析一个操作(或行)吗?
EN

Stack Overflow用户
提问于 2012-03-19 02:45:15
回答 1查看 82关注 0票数 0

我正在对两种搜索算法的缓存行为进行基准测试,这两种算法使用Cachegrind对排序的项目范围进行操作。我在一个向量中有n个项目,另一个向量包含所有有效的索引。我对第二个向量使用std::random_shuffle,然后对第一个向量中的项执行n次成功的查找。我正在进行基准测试的函数大致如下:

代码语言:javascript
复制
template <typename Iterator>
void lookup_in_random_order(Iterator begin, Iterator end)
{
    const std::size_t N = std::distance(begin, end);
    std::vector<std::size_t> idx(N);
    std::iota(idx.begin(), idx.end(), 0);

    std::srand(std::time(0));
    std::random_shuffle(idx.begin(), idx.end());

    // Warm the cache -- I don't care about measuring this loop.
    for(std::size_t i = 0; i < N; ++i)
        my_search(begin, end, idx[i]);

    std::random_shuffle(idx.begin(), idx.end());

    // This one I would care about!
    for(std::size_t i = 0; i < N; ++i)
    {
        int s = idx[i];
        // Especially this line, of course.
        my_search(begin, end, s);
    }
}

我使用g++ (使用-g和-O2)编译我的代码。我先运行Cachegrind,然后运行cg_annotate。我得到了类似如下的内容:

代码语言:javascript
复制
       Ir I1mr ILmr        Dr    D1mr    DLmr Dw D1mw DLmw
        .    .    .         .       .       .  .    .    .  template <typename Iterator>
       17    2    2         0       0       0  6    0    0  void lookup_in_random_order(Iterator begin, Iterator end)
        .    .    .         .       .       .  .    .    .  {
        .    .    .         .       .       .  .    .    .      const std::size_t N = std::distance(begin, end);
        .    .    .         .       .       .  .    .    .      std::vector<std::size_t> idx(N);
        .    .    .         .       .       .  .    .    .      std::iota(idx.begin(), idx.end(), 0);
        .    .    .         .       .       .  .    .    .      
        4    0    0         0       0       0  2    1    1      std::srand(std::time(0));
        .    .    .         .       .       .  .    .    .      std::random_shuffle(idx.begin(), idx.end());
        .    .    .         .       .       .  .    .    .  
3,145,729    0    0         0       0       0  0    0    0      for(std::size_t i = 0; i < N; ++i)
        .    .    .         .       .       .  .    .    .              my_search(begin, end, idx[i]);
        .    .    .         .       .       .  .    .    .  
        .    .    .         .       .       .  .    .    .      std::random_shuffle(idx.begin(), idx.end());
        .    .    .         .       .       .  .    .    .  
3,145,729    1    1         0       0       0  0    0    0      for(std::size_t i = 0; i < N; ++i)
        .    .    .         .       .       .  .    .    .      {
1,048,575    0    0 1,048,575 132,865 131,065  0    0    0              int s = idx[i];
        .    .    .         .       .       .  .    .    .              my_search(begin, end, s);
        .    .    .         .       .       .  .    .    .      }
        7    0    0         6       1       1  0    0    0  }

出于某些原因,有些代码行(尤其是最有趣的那行!)由点组成。现在,Cachegrind manual说“不适用于一条线的事件用点表示。这对于区分不能发生的事件和可以但没有发生的事件很有用。”

应该如何解释这一点?我的第一个想法是,也许编译器会优化我的搜索。我认为这是不可能的,因为程序确实花了相当多的时间运行。尽管如此,我还是试着在不使用-O2标志的情况下进行编译,现在调用my_search的每一行代码都记录了一些数字(再也没有点了!)然而,由于显而易见的原因,这似乎不是正确的方法。

一般来说,有没有办法告诉Cachegrind“特别注意这一行,我很感兴趣它会导致多少缓存未命中”?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-19 05:33:30

我的猜测是,在O2中,它允许编译器执行函数的自动内联,您可以在其中看到点。Cachegrind将不会看到内联函数调用,因为调用已经消失。尝试"-fno-inline“(Compiler options)

当然,在使用和不使用内联的情况下,您可能会有不同的缓存性能数字。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9761175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档