小编VAn*_*rei的帖子

在'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万
查看次数

是否存在导致50%分支预测未命中的代码?

问题:

我试图找出如何编写代码(C preffered,ASM仅在没有其他解决方案的情况下),这将使分支预测在50%的情况下失败.

所以它必须是一段代码"对于与分支相关的编译器优化"是"imune",而且所有HW分支预测都不应该超过50%(抛硬币).即使是更大的挑战,也能够在多个CPU架构上运行代码并获得相同的50%未命中率.

我设法编写了一个在x86平台上达到47%分支未命中率的代码.我怀疑失踪可能有3%来自:

  • 程序启动开销已经分支(尽管很小)
  • Profiler开销 - 基本上对于每个计数器读取都会引发中断,因此可能会添加其他可预测的分支.
  • 在后台运行的系统调用包含循环和可预测的分支

我编写了自己的随机数生成器,以避免调用rand,它的实现可能隐藏了可预测的分支.当可用时它也可以使用rdrand.延迟对我来说无关紧要.

问题:

  1. 我能比我的代码版做得更好吗?更好的意思是为所有CPU架构获得更高的分支错误预测和相同的结果.
  2. 这段代码可以预测吗?那是什么意思?

代码:

#include <stdio.h>
#include <time.h>

#define RDRAND
#define LCG_A   1103515245
#define LCG_C   22345
#define LCG_M   2147483648
#define ULL64   unsigned long long

ULL64 generated;

ULL64 rand_lcg(ULL64 seed)
{
#ifdef RDRAND
    ULL64 result = 0;
    asm volatile ("rdrand %0;" : "=r" (result));
    return result;
#else
    return (LCG_A * seed + LCG_C) % LCG_M;
#endif
}

ULL64 rand_rec1()
{ …
Run Code Online (Sandbox Code Playgroud)

c c++ performance computer-architecture compiler-optimization

22
推荐指数
1
解决办法
2162
查看次数

是否有"保留"缓存分数的解决方法?

假设我必须编写一个C或C++计算密集型函数,它有2个数组作为输入,一个数组作为输出.如果计算使用2个输入数组的频率高于更新输出数组,那么我最终会遇到输出数组很少被缓存的情况,因为它被驱逐以获取2个输入数组.

我想为输出数组预留一小部分缓存,并强制执行这些行一旦被提取就不会被驱逐,以便始终在缓存中写入部分结果.

Update1(output[]) // Output gets cached
DoCompute1(input1[]); // Input 1 gets cached
DoCompute2(input2[]); // Input 2 gets cached
Update2(output[]); // Output is not in the cache anymore and has to get cached again
...
Run Code Online (Sandbox Code Playgroud)

我知道有一些机制可以帮助驱逐:clflush,clevict,_mm_clevict等.是否有相反的机制?

我在考虑3种可能的解决方案:

  • 如果已被驱逐,则不时使用_mm_prefetch来获取数据.然而,这可能会产生不必要的流量加上我需要非常小心何时引入它们;
  • 尝试对较小的数据块进行处理.然而,只有在问题允许的情况下,这才有效;
  • 禁用硬件预取程序可以降低不必要的驱逐率.

除此之外,还有什么优雅的解决方案吗?

c c++ optimization caching memory-management

13
推荐指数
1
解决办法
290
查看次数

使用GCC优化C/C++中循环内的嵌套if语句

我正在使用GCC编译器测试C/C++中的各种优化.我目前有一个包含多个嵌套if语句的循环.条件是在程序执行开始时计算的.看起来有点像这样:

bool conditionA = getA();
bool conditionB = getB();
bool conditionC = getC();
//Etc.

startTiming();

do {
    if(conditionA) {
        doATrueStuff();
        if(conditionB) {
            //Etc.
        } else {
            //Etc.
        }
    } else {
        doAFalseStuff();
        if(conditionB) {
            //Etc.
        } else {
            //Etc.
        }
    }
} while (testCondition());

endTiming();
Run Code Online (Sandbox Code Playgroud)

doATrueStuff()内联函数在哪里进行一些简单的数值计算,因此调用它没有任何开销.

不幸的是,不能事先定义条件,它们必须在运行时计算.我们甚至无法可靠地预测他们是真是假的可能性.getA()也许是rand()%2.但经过计算,它们的价值永远不会改变.

我想到了两个解决方案,一个是全局函数指针,用于在循环中调用适当的函数,如下所示:

void (*ptrA)(void);
//Etc.

int main(int argc, char **argv) {
    //...
    if (conditionA) {
        ptrA=&aTrueFunc;
    } else {
        ptrA=&aFalseFunc;
    }
    //...
    do {
        (*ptrA)();
    } while (testCondition());
    //... …
Run Code Online (Sandbox Code Playgroud)

c c++ optimization gcc loops

9
推荐指数
1
解决办法
2578
查看次数

测量Unix域套接字的延迟

我想比较两个进程之间的Unix域套接字的性能与另一个进程的性能.

我有一个基本程序,它创建一个套接字对,然后调用fork.然后,它测量RTT以将8192个字节发送到另一个进程并返回(每次迭代都不同).

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

int main(int argc, char **argv) {
    int i, pid, sockpair[2];
    char buf[8192];
    struct timespec tp1, tp2;

    assert(argc == 2);

    // Create a socket pair using Unix domain sockets with reliable,
    // in-order data transmission.
    socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair);

    // We then fork to create a child process and then start the benchmark.
    pid = fork();

    if (pid == 0) { …
Run Code Online (Sandbox Code Playgroud)

c unix sockets performance benchmarking

8
推荐指数
1
解决办法
936
查看次数

Visual Studio 2013优化标志(/ O2 vs/Ox)

我一直在尝试通过MSDN页面阅读各种优化标志.

我们目前的大多数项目都设置/O2为"最大化速度".

我的困惑是这究竟是什么意思.关于/O2国旗,下列哪一项陈述更接近真实?

  1. 优化速度和大小的代码,但是如果存在争用优选速度优化
  2. 针对速度优化代码,不针对大小进行优化.

我提出我们应该使用/Ox旗帜的论点,但那时我认为选项2是真的.

我基本上被告知"我们不会改变/O2,/Ox除非有人有确凿的证据证明我们需要这样做".

所以我的问题是/O2仍然执行内存优化?例如,返回值优化,复制省略等.从切换/O2/Ox

c++ optimization performance compiler-optimization visual-studio-2013

7
推荐指数
2
解决办法
5849
查看次数

处理器中的 DMA 控制器有何用途?

DMA 控制器存在于磁盘、网络设备上。因此他们可以直接将数据传输到主存储器。那么处理器芯片内部的DMA控制器有什么用?我还想知道,处理器芯片外部是否有不同的总线(i2c,pci,spi)而处理器内部只有一条总线(AXI)。这是如何工作的?(应该\xe2\x80\x99t它会导致一些瓶颈)

\n

performance memory-management cpu-architecture dma

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

系统范围的分析器(例如perf)如何将计数器与指令相关联?

我试图了解系统范围的分析器是如何工作的.我们以linux perf为例.对于某个分析时间,它可以提供:

  • 各种聚合的软件性能计数器
  • 每个用户空间进程和内核空间函数花费的时间和硬件计数器(例如#instructions)
  • 有关上下文切换的信息
  • 等等

我几乎可以肯定的是,报告只是对实际情况的估计.所以我认为有一些内核模块以一定的采样率启动软件中断.采样率越低,分析器开销越低.中断可以读取存储性能计数器的模型特定寄存器.

下一部分是将计数器与机器上运行的软件相关联.这是我不理解的部分.

  1. 那么探查器从何处获取数据?

  2. 您是否可以查询任务计划程序以查明中断他时正在运行的内容?这不会影响调度程序的执行(例如,不是继续中断的函数,而是只调度另一个,使得分析器结果不准确).task_struct对象列表是否可用?

  3. 即使在指令级,分析器如何甚至关联硬件指标?

optimization performance profiling operating-system linux-kernel

5
推荐指数
2
解决办法
1931
查看次数

解释perf属性输出

我开发了一个代码,可以输入一个大的2-D图像(最高64MPixels)和:

  • 在每一行上应用过滤器
  • 转置图像(使用阻止以避免大量缓存未命中)
  • 在图像的列(现在行)上应用过滤器
  • 将过滤后的图像转换回来进行其他计算

虽然它没有改变某些东西,但为了完整性我的问题,过滤是应用离散小波变换,代码是用C语言编写的.

我的最终目标是尽可能快地运行.到目前为止,通过使用阻塞矩阵转置,矢量化,多线程,编译器友好的代码等,我的速度提高了10倍以上.

来到我的问题:我所使用的代码的最新分析统计数据让我perf stat -e感到困扰.

        76,321,873 cache-references                                            
     8,647,026,694 cycles                    #    0.000 GHz                    
     7,050,257,995 instructions              #    0.82  insns per cycle        
        49,739,417 cache-misses              #   65.171 % of all cache refs    

       0.910437338 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)

(缓存未命中数)/(#指令)低约0.7%.这里提到这个数字是检查内存效率的好事.

另一方面,高速缓存未命中高速缓存引用的百分比非常高(65%!),正如我所看到的那样,可以表明在高速缓存效率方面执行出现问题.

详细的统计数据perf stat -d是:

   2711.191150 task-clock                #    2.978 CPUs utilized          
         1,421 context-switches          #    0.524 K/sec                  
            50 cpu-migrations            #    0.018 K/sec                  
       362,533 page-faults               #    0.134 M/sec                  
 8,518,897,738 cycles                    #    3.142 GHz                     [40.13%]
 6,089,067,266 stalled-cycles-frontend   #   71.48% frontend …
Run Code Online (Sandbox Code Playgroud)

optimization performance caching computer-architecture perf

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

GCC -flto改变符号可见性

我有一大段代码,-flto只在某些版本的gcc上编译时会产生错误.我将在下面总结一下

在file1.h

extern char A [100];
Run Code Online (Sandbox Code Playgroud)

在file1.c中

#include "file1.h"
char A[100];
Run Code Online (Sandbox Code Playgroud)

我也有一些使用变量的c ++代码A.C++代码被编译成一个.o文件,然后整个事情被编译成类似的东西

gcc file1.c cpp.o
Run Code Online (Sandbox Code Playgroud)

在archlinux(5.2.0)上使用gcc版本,无论是否有问题都没有-flto.但是在Ubuntu 14.04(4.8.4)上使用gcc时,编译代码时-flto,A会成为局部变量.我用nm证实了这一点:

这些是有nm a.out问题变量的输出

Ubuntu,没有lto(拱门类似,有不同的编号):

00000000006162e0 B A
Run Code Online (Sandbox Code Playgroud)

Ubuntu,lto

00000000006092c0 b A.2722
Run Code Online (Sandbox Code Playgroud)

我的理解是,它B是一个全局变量,而b不是.

A即使我-flto在Ubuntu上使用,如何确保将其保持为全局变量?

c c++ optimization gcc compilation

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

如何编写简单的"页面错误生成器"?

对于我在Linux Kernel上的课程项目,我需要模拟由于内存不足而导致大量页面交换的情况.

我想编写一个需要大量物理内存的程序,因此该程序访问的页面必须多次交换.

c memory kernel memory-management microbenchmark

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

如何获取程序执行的指令数?

我编写并交叉编译了一个小型的c ++程序,我可以在ARM或PC上运行它.由于ARM和PC具有不同的指令集架构,我想比较它们.我可以在这个c ++程序中为两个ISA获取执行指令的数量吗?

c++ x86 profiling arm instruction-set

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