El camino a BPF: antecedentes técnicos

Tabla de contenido

introducción

¿Qué es BPF?

historia

composición

mecanismo de ejecución

Relación entre BPF y ebpf

BCC, bpftrace, Visor de E/S

Inicio rápido del proyecto BCC

ejecutivosnoop

biolatencia

Instrumentación dinámica: kprobes y uprobes

concepto

defecto

Instrumentación estática: tracepoint y USDT

concepto

defecto

solución recomendada

Introducción a bpftrace: seguimiento de openat

experiencia técnica

BPF gráfico

Funciones auxiliares de BPF

bpf_probe_read()

¿Por qué bpf_probe_read deshabilita las interrupciones de fallas de página?

Cómo bpf_probe_read prohíbe la interrupción por falla de página

muestra

Comandos de llamada al sistema BPF

Usando strace para analizar execsnoop

Tipo de programa BPF

Tipo de mapa BPF

Control de concurrencia BPF

Interfaz BPF sysfs

Formato de tipo BPF

BPF NÚCLEO

Limitaciones de BPF

seguimiento de la pila de llamadas

Seguimiento de la pila de llamadas basado en el puntero del marco

Hacer depuración basada en información de depuración

último registro de sucursal

ORCO

símbolo

gráfico de llama

origen del evento

Ksondas

sube

punto de rastreo punto de rastreo

USDT

Contadores de supervisión del rendimiento


introducción

¿Qué es BPF?

historia

Es la abreviatura de Berkeley Packet Filter, que nació en 1992 para mejorar el rendimiento de las herramientas de filtrado de paquetes de red.

Entró en la línea principal del kernel de Linux en 2014.

En cuanto a la forma en que se usa, se parece más a JavaScript.

composición

Conjunto de instrucciones, objetos de almacenamiento, funciones auxiliares y otras partes.

mecanismo de ejecución

En general, existen dos mecanismos de ejecución:

  1. intérprete
  2. Un compilador JIT justo a tiempo que convierte dinámicamente las instrucciones BPF en instrucciones localizadas

Antes de la ejecución, debe pasar la verificación de seguridad del validador, lo que puede garantizar que el programa BPF en sí no se bloquee.

Relación entre BPF y ebpf

La ebpf actual sigue denominándose BPF para ser coherente con la anterior.

BCC, bpftrace, Visor de E/S

Es engorroso escribir programas BPF directamente a través de instrucciones BPF, por lo que existe un lenguaje de alto nivel para admitirlo.

BCC (BPF Compiler Collection, BPF) se utilizó por primera vez para desarrollar programas de rastreo BPF, proporcionó un entorno de lenguaje C y también proporcionó entornos lua y python para implementar interfaces del lado del usuario. Fue el predecesor de las bibliotecas libbcc y libbpf. La biblioteca proporciona funciones de biblioteca para observar eventos con programas BPF.

La biblioteca de funciones de BCC proporciona más de 70 herramientas.

bpftrace es un front-end emergente que brinda soporte de lenguaje de alto nivel específicamente para crear herramientas BPF. bpftrace también se basa en las bibliotecas libbcc y libpbf.

bpftrace es bueno para escribir potentes programas de una línea y scripts cortos, mientras que BCC desarrolla principalmente procesos de back-end a gran escala relativamente complejos.

BCC y bpftrace no pertenecen al kernel de linux, pero pertenecen a una fundación IO ViSor linux en GITHUB.

Inicio rápido del proyecto BCC

ejecutivosnoop

Desde el proyecto bcc, funciona rastreando la llamada al sistema execve.

sudo execsnoop-bpfcc

efecto

Puede usar esta herramienta para verificar la carga del negocio, es decir, puede ver si el proceso se crea en un período determinado de acuerdo con sus propias ideas.

biolatencia

concepto

Dibuje un histograma de latencia de dispositivo de bloque (latencia de E/S de disco)

sudo biolatency-bpfcc

En el entorno de la máquina virtual, este comando no se ejecutará con la versión del kernel: 5.19.0-35-generic.

Instrumentación dinámica: kprobes y uprobes

concepto

Inserte puntos de observación en ubicaciones de instrucciones arbitrarias en un programa que se ejecuta en producción

defecto

A medida que se cambia la versión, la función instrumentada puede cambiar de nombre o eliminarse directamente, lo que causará problemas de estabilidad y la herramienta BPF puede no funcionar directamente.

Instrumentación estática: tracepoint y USDT

concepto

En esencia, es para resolver el problema de la estabilidad de la interfaz en la instrumentación dinámica anterior y codificar directamente el nombre del evento estable en el código, que es mantenido directamente por el desarrollador.

USDT (seguimiento definido estáticamente a nivel de usuario) describe esta tecnología.

defecto

La codificación rígida introduce costos de mantenimiento adicionales

solución recomendada

Primero use tecnología de seguimiento estático (tracpoint o USDT) y luego use tecnología de instrumentación dinámica si no es suficiente.

Introducción a bpftrace: seguimiento de openat

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat {printf("%s %s \n",comm,str(args->filename));}'

Aquí hay algunos pequeños consejos:

  1. openat se llama muchas más veces que open en linux
  2. bpftrace debe usar privilegios de root
  3. bpftrace es generalmente simple y admite algunas herramientas de comando relativamente pequeñas, pero la herramienta BCC es más poderosa

experiencia técnica

BPF gráfico

Funciones auxiliares de BPF

  1. Funciones de operación de mapas: BPF_MAP_LOOKUP_ELEM, BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM, etc.
  2. Funciones de operación de memoria: BPF_MEMCPY, BPF_MEMCPY_STR, BPF_MEMSET, etc.
  3. Funciones de operación de red: BPF_SOCK_OPS_TCP_SOCK, etc.
  4. Funciones de operación de tiempo: BPF_KTIME_GET_NS, etc.
  5. Funciones de operación de llamadas al sistema: BPF_TRACE_PRINTK, BPF_GET_CURRENT_PID_TID, etc.
  6. Funciones de cálculo matemático: BPF_ADD, BPF_SUB, BPF_MUL, BPF_DIV, etc.
  7. Otras funciones: BPF_DEBUG, BPF_EXIT, etc.

bpf_probe_read()

El acceso a la memoria en BPF está limitado a registros BPF y espacio de pila (y acceso a tablas de mapeo BPF a través de funciones auxiliares).Si accede a otra memoria (por ejemplo, memoria que no sea BPF), necesita usar bpf_probe_read().

Esta función verifica la seguridad del proceso y prohíbe las interrupciones por fallas de página para garantizar que no se produzcan interrupciones por fallas de página en el contexto de la sonda (de lo contrario, puede causar problemas en el núcleo).

Hay otras funciones auxiliares: bpf_probe_read_kernel, bpf_probe_read_user()

¿Por qué bpf_probe_read deshabilita las interrupciones de fallas de página?


En el kernel de Linux, los programas BPF pueden acceder a la memoria del espacio del usuario en el espacio del kernel. Cuando la página en el espacio de direcciones del espacio de usuario al que accede el programa BPF no está en la memoria física, se activará una interrupción de falla de página y luego el kernel leerá la página correspondiente del disco en la memoria para completar la asignación de memoria física. Este proceso requiere mucho tiempo.

Sin embargo, en algunos casos, es posible que no necesitemos leer la página correspondiente a la interrupción de falla de página inmediatamente, por ejemplo, cuando procesamos paquetes de datos de red de alta velocidad, no podemos soportar demasiado retraso. Por lo tanto, podemos evitar la asignación de memoria física que consume mucho tiempo y mejorar el rendimiento del procesamiento al deshabilitar las interrupciones de fallas de página.

Cómo bpf_probe_read prohíbe la interrupción por falla de página

Es necesario configurar el bit de indicador de interrupción de falla de la página de salida del hilo actual

/* 禁用缺页中断 */ 
void disabled_page_fault(void) 
{ 
    preempt_disable(); 
    actual->banderas |= PF_NOFREEZE; 
    actual->mm->def_flags |= VM_FAULT_NOPAGE; 
}

muestra

Use la función bpf_probe_read para leer paquetes UDP en skb

El proceso de lectura del paquete de datos UDP necesita leer primero el encabezado IP, luego determinar el protocolo de capa superior como UDP de acuerdo con el campo de tipo de protocolo IP, luego leer el encabezado UDP y luego leer la carga útil de datos. El siguiente es un código de muestra para leer paquetes UDP usando la función bpf_probe_read()

#include <linux/bpf.h> 
#include <linux/if_ether.h> 
#include <linux/ip.h> 
#include <linux/udp.h> 

int mybpf_prog(struct __sk_buff *skb) 
{ 
    void *data = ( vacío *)(largo)skb->datos; 
    vacío *fin_datos = (vacío *)(largo)skb->fin_datos; 

    estructura ethhdr *eth = datos; 
    si (eth + 1 > data_end) 
        devuelve 0; 
    
    // 读取IP头
    struct iphdr iph; 
    if (bpf_probe_read(&iph, sizeof(iph), (void *)(eth + 1)) != 0) 
        devuelve 0; 

    if (iph.protocol == IPPROTO_UDP) { 
        // 读取UDP头
        struct udphdr uh; 
        if (bpf_probe_read(&uh, sizeof(uh), (void *)((unsigned char *)iph + (iph.ihl * 4))) !
            devolver 0; 
            
        // 计算数据包总长度
        unsigned int len ​​​​= ntohs(iph.tot_len) - (iph.ihl * 4) - sizeof(uh); 
        if (len <= 0) // error de longitud del paquete 
            devuelve 0; 
            
        // carga útil de datos de lectura 
        carga útil de caracteres sin firmar[ len]; 
        if (bpf_probe_read(&payload, len, (void *)((unsigned char *)uh + sizeof(uh))) != 0) 
            return 0; 

        // Procesar la carga de datos leídos 
        ... 
        
        return 1; 
    } 

    devuelve 0; 
}

Comandos de llamada al sistema BPF

Usando strace para analizar execsnoop

sudo strace -ebpf execsnoop-bpfcc

bpf(BPF_BTF_LOAD, {btf="\237\353\1\0\30\0\0\0\0\0\0\0\274\4\0\0\274\4\0\0H\17 \0\0\0\0\0\0\0\0\0\2"..., btf_log_buf=NULO, btf_size=5148, btf_log_size=0, btf_log_level=0}, 28) = 3 bpf(BPF_PROG_LOAD 
, {map_type=BPF_MAP_TYPE_PERF_EVENT_ARRAY, key_size=4, value_size=4, max_entries=128, map_flags=0, inner_map_fd=0, map_name="events", map_ifindex=0, btf_fd=0, btf_key_type_id=0, btf_value_type_id=0, btf_vmlinux_value_type_id= 0 , mapa_extra=0}, 72) = 4
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_KPROBE, insn_cnt=510, insns=0x7ff36007d000, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(5, 19, 17), prog_flags=0, prog_name="syscall__execve", prog_ifindex=0, tipo_de_conexión_esperado=BPF_CGROUP_INET_INGRESS, prog_btf_fd=3, func_info_rec_size=8, func_info=0x5645a446e430, func_info_cnt=1, line_info_rec_size=16, line_info=0x5645a4a88f2 0, línea_info_cnt=252, adjunto_btf_id=0, adjunto_prog_fd=0, fd_array=NULO}, 144) = 5
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_KPROBE, insn_cnt=82, insns=0x7ff36021b7d0, licencia="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(5, 19, 17), prog_flags=0, prog_name="do_ret_sys_exec", prog_ifindex=0, tipo_de_conexión_esperado=BPF_CGROUP_INET_INGRESS, prog_btf_fd=3, func_info_rec_size=8, func_info=0x5645a446e430, func_info_cnt=1, line_info_rec_size=16, line_info=0x5645a348d 760, línea_info_cnt=28, adjunto_btf_id=0, adjunto_prog_fd=0, fd_array=NULL}, 144) = 7 
PCOMM PID PPID RET ARGS 
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x7ff35babc690, value=0x7ff35babc590, flags=BPF_ANY}, 144) = 0 bpf(BPF_MAP_UPDATE_ELEM, {map_fd= 4, 
clave =0x7ff35babc590, value=0x7ff35babc690, flags=BPF_ANY}, 144) = 0 
^Cstrace: Proceso 4540 desconectado

PD: es mejor evitar usar strace directamente porque usar strace esencialmente usa ptrace, lo que reducirá seriamente la velocidad de ejecución del proceso de destino, y el rendimiento puede caer directamente al 1% del original, pero su ventaja es que puede soportar La traducción de llamadas al sistema bpf, por ejemplo, puede imprimir BPF_PROG_LOAD

Tipo de programa BPF

Los diferentes tipos de programas bpf definen los tipos de eventos que un programa BPF puede montar, así como los parámetros de los eventos.Los tipos de programas BPF que se utilizan principalmente con fines de rastreo son los siguientes:

Tipo de mapa BPF

Entre ellos, BPF_MAP_TYPE_PERF_EVENT_ARRAY puede transferir la información capturada en el kernel al usuario, y execsnoop usa este tipo.

Control de concurrencia BPF

BPF siempre ha carecido de control de concurrencia hasta que Linux 5.1 agregó asistentes de bloqueo de giro, aunque aún no están disponibles para rastreadores.

Con el seguimiento, los subprocesos paralelos pueden buscar y actualizar los campos del mapa BPF en paralelo, lo que provoca daños cuando un subproceso sobrescribe una actualización de otro. Esto también se conoce como el problema de actualización perdida (lost update), es decir, la superposición de lecturas y escrituras simultáneas conduce a la pérdida de actualizaciones. Trace front-end BCC y bpftrace usan tipos de mapa de matriz y hash por CPU siempre que sea posible para evitar esta corrupción. Esto creará instancias para cada CPU lógica (digamos usando BPF_MAP_TYPE_PERCPU_HASH con tipo PERCPU)

Así se usa el tipo BPF_MAP_TYPE_PERCPU_HASH

strace -febpf bpftrace -e 'k:vfs_read { @ = cuenta(); }'

Esta es la forma sin utilizar el control de concurrencia

strace -febpf bpftrace -e 'k:vfs_read { @++; }'

La comparación de los recuentos muestra que el hash normal subestima los eventos en un 0,01 %.

Habrá un error de 0.01% en comparación.

Interfaz BPF sysfs

En Linux 4.4, BPF introdujo comandos para exponer programas y mapas BPF a través de un sistema de archivos virtual, generalmente montado en /sys/fs/bpf. Esto se llama "fijar", y se puede utilizar de muchas maneras. Permite crear programas BPF persistentes, similares a demonios, y continuar ejecutándose después de que finaliza el proceso que los cargó. También proporciona otra forma para que los programas de la zona del usuario interactúen con los programas BPF en ejecución: pueden leer y escribir mapas BPF.

Formato de tipo BPF

Si nos falta el código fuente del programa de destino, lo que dificulta la escritura de algunas herramientas BPF, aquí hay una tecnología BTF que puede resolver este problema.

Pero la tecnología BTF aún está en desarrollo.

BPF NÚCLEO

El proyecto Compile Once - Run Everywhere de BPF tiene como objetivo permitir que los programas BPF se compilen en el código de bytes BPF una vez, se guarden y luego se distribuyan y ejecuten en otros sistemas. Esto evitará la instalación de compiladores BPF (LLVM y Clang) en todas partes, lo cual es un desafío para Linux integrado con limitaciones de espacio. También evita los costos de CPU y memoria en tiempo de ejecución de ejecutar un compilador al ejecutar herramientas de observabilidad BPF.

CO-RE también está actualmente en desarrollo.

Limitaciones de BPF

  1. No utilice las funciones del núcleo a voluntad.
  2. El tamaño de la pila BPF no puede exceder 512 (MAX_BPF_STACK).Hay una solución para esto: use espacio de almacenamiento mapeado.

seguimiento de la pila de llamadas

BPF proporciona una estructura de tabla de mapeo dedicada para almacenar información de la pila de llamadas, que puede guardar información de seguimiento de la pila de llamadas basada en punteros de tramas o en ORC.

Seguimiento de la pila de llamadas basado en el puntero del marco

Esta tecnología se basa principalmente en una premisa: el encabezado de la lista de marcos de la pila de llamadas de función siempre se almacena en un registro determinado (RBP en x86_64), y la dirección de retorno de esta llamada de función siempre se encuentra en la posición señalada por RBP. valor más un desplazamiento fijo (+8).

Esto indica que cualquier depurador puede realizar fácilmente un seguimiento de la pila después de interrumpir la ejecución del programa recorriendo la lista vinculada encabezada por el valor RBP después de leer el RBP y obtener la dirección de retorno en una posición de desplazamiento fija.

PD: en el compilador gcc, no hay un puntero de marco de función de forma predeterminada, y RBP se usa como un registro ordinario, pero la mejora del rendimiento no es muy alta, por lo que se recomienda habilitar este comportamiento predeterminado.

-fno-omitir-frame-puntero

Hacer depuración basada en información de depuración

Eso es agregar -g -wall después de gcc.

Contiene la información de depuración de ELF de DWARF

Los segmentos de archivo relacionados con la depuración en el archivo ELF son .eh_frame y .debug_frame

La desventaja es que esto hace que el ejecutable sea muy grande.

libjvm.so = 17M

libjvmd.so = 222M

último registro de sucursal

Es decir, LBR es una tecnología especial de inter, que se registra en el búfer de hardware.Esta tecnología no tiene sobrecarga adicional.

Pero habrá límites para la profundidad de los registros de soporte.

BPF no es compatible con LBR

ORCO

Un nuevo formato de información de depuración: la capacidad de rebobinado Oops (ORC) está especialmente diseñada para los requisitos de seguimiento de la pila. En comparación con el formato DWARF, el uso de este formato tiene requisitos más bajos para los procesadores. ORC también usa segmentos de archivos ELF, y el kernel de Linux actual brinda algo de soporte.

En la actualidad, no hay desarrollo de soporte para la pila de llamadas ORC en modo de usuario.

La función perf_callchain_kernel puede admitir el seguimiento de la pila de llamadas basada en ORC en el kernel.

símbolo

La información de la pila de llamadas se registra actualmente en forma de datos de direcciones en el kernel, y estas direcciones se pueden traducir a símbolos (como nombres de funciones) mediante programas en modo de usuario.

Pero esta parte del trabajo aún no está completa.

gráfico de llama

Un gráfico de llamas es una herramienta de visualización para mostrar el uso de la CPU de un programa. Aquí hay algunos métodos básicos de uso e interpretación de los gráficos de llama:

  1. Eje de coordenadas: el eje Y del gráfico de llamas identifica la pila de llamadas y representa la profundidad de las llamadas a funciones de arriba a abajo. El eje x representa el tiempo de CPU (que puede estar en milisegundos, segundos u otras unidades), y de izquierda a derecha representa el tiempo de ejecución del programa.
  2. Color: el color del gráfico de llamas indica el valor relativo del tiempo de CPU o el espacio de contador consumido por las llamadas a funciones.
  3. Ancho: el ancho de cada rectángulo en el gráfico de llamas representa el tiempo de CPU o la medida del contador para el código en cuestión.
  4. Herramientas: por ejemplo, Flamegraph, perf y otras herramientas de generación de gráficos de llama admiten la habilitación de varias configuraciones, como el orden de los rectángulos, los esquemas de color, etc.

Con base en la información anterior, aprendamos cómo interpretar el gráfico de llama:

  1. Comienzo y final: el comienzo y el final de un gráfico de llamas suelen ser los puntos de entrada y salida de un programa y, por lo general, tienen placas bastante anchas y colores más claros en los gráficos de llamas.
  2. Ancho: un rectángulo con un ancho mayor en el gráfico de la llama indica que el consumo de recursos durante la ejecución del programa es relativamente alto y que el tiempo de ejecución del código es correspondientemente más largo.
  3. Color: El color en el gráfico de la llama varía de verde claro a verde oscuro. El área verde claro es un área relativamente lenta y de baja sobrecarga en el programa, y ​​el área verde oscuro persigue un mayor consumo de tiempo.
  4. Llamadas repetidas: en el gráfico de llamas, las llamadas repetidas de la misma función mostrarán el mismo cuadro, y el ancho del cuadro indica la cantidad de veces que se llamó y el tamaño relativo del tiempo de ejecución.
  5. Información de la pila: el nombre y la información de la pila de llamadas de cada llamada de función en el gráfico de llamas también se pueden usar para identificar y ajustar problemas de rendimiento en el programa.

origen del evento

Ksondas

El concepto de kprobes y kretprobes

kprobes proporciona soporte de instrumentación dinámica para el kernel sin reiniciar el kernel.

kretprobes se puede usar para instrumentar el valor de retorno de la función del kernel para obtener el valor de retorno, o usar kprobes y kretprobes para instrumentar una función al mismo tiempo para obtener la hora de una llamada de función del kernel.

principio

  1. Registro de puntos de interrupción: Kprobes utiliza la tecnología de asignación de memoria dinámica del kernel para registrar puntos de interrupción en ubicaciones clave en el código del servidor web del kernel.
  2. Activación del punto de interrupción: cuando el kernel se ejecuta en la posición del punto de interrupción registrado, suspende inmediatamente la ejecución y comienza a ejecutar el controlador registrado por Kprobes en este momento.
  3. Manejador: un manejador para Kprobes puede ser una función definida por el usuario que puede vincularse a una llamada de función del kernel en un punto de interrupción y registrar datos de rendimiento o cambiar el estado del kernel con fines de depuración o creación de perfiles.
  4. Procesamiento completado: una vez que se completa el programa de procesamiento, Kprobes continuará ejecutando el código restante en la ubicación interrumpida y completará el rastreo o el procesamiento del código del kernel.

Interfaz de Kprobes

Debe usar el lenguaje c para escribir la función de procesamiento del puerto y la función de procesamiento de retorno, y luego llamar a register_kprobe () para registrarse.

Utilice principalmente BCC o bpftrace ahora.

BCC proporciona:

adjuntar_kprobe() 
adjuntar_kretprobe()

Una demostración de bpftrace es la siguiente:

bpftrace -e 'kprobe:vfs_* {@[probe] = cuenta()}'

sube

concepto

Proporciona instrumentación dinámica de programas de modo de usuario.

Similar a kprobes, el principio es similar a kprobes.

principio

Al insertar una instrucción de salto en una dirección específica, se intercepta el flujo de ejecución de la CPU que ingresa o sale de la dirección, y el programa de procesamiento especificado se ejecuta antes y después. Este método puede monitorear y modificar el estado de ejecución del programa sin destruir el código binario

interfaz

Basado en Ftrace, para /sys/kernel/debug/tracing/uprobe_events: abra o cierre uprobes escribiendo una cadena específica en este archivo

perf_event_open()

Se proporcionan dos interfaces en BCC:

adjuntar_uprobe 
adjuntar_uretprobe

punto de rastreo punto de rastreo

concepto

Instrumentación estática

principio

Al escribir el código del kernel, los desarrolladores pueden usar definiciones de macros de puntos de seguimiento para predefinir puntos de seguimiento. Estos puntos de seguimiento y sus parámetros se fijan en el binario del kernel en el momento de la compilación.

Cuando el programa se está ejecutando, si la función de seguimiento está habilitada, cuando el programa se ejecuta en el punto de seguimiento correspondiente, se activará la función de devolución de llamada del punto de seguimiento correspondiente. Esta función de devolución de llamada se puede definir en el código para implementar las operaciones requeridas. Dado que los puntos de seguimiento se han definido de antemano, es posible evitar la inserción de instrucciones de ensamblaje adicionales, lo que reduce el impacto en el rendimiento del programa.


interfaz

BCC proporciona

rastrearpunto_sonda()

USDT

concepto

Seguimiento estático predefinido en modo de usuario, que proporciona un mecanismo de punto de seguimiento del espacio del usuario

BPF y USDT

USDT().enable_probe()

Contadores de supervisión del rendimiento

Los contadores de supervisión del rendimiento son contadores que se utilizan para medir varios estados del hardware del sistema durante la ejecución del programa. Por lo general, los proporciona el hardware subyacente del procesador, y se puede usar una gran cantidad de contadores que se ejecutan en el sistema para monitorear el rendimiento y los cuellos de botella del sistema. Los contadores de monitoreo de rendimiento pueden medir varios indicadores, como la ejecución de instrucciones, el rendimiento de la memoria caché de la CPU, el resumen de la memoria, etc., y luego evaluar el rendimiento de todo el sistema y el efecto de las soluciones de optimización.

En el proceso de desarrollo de software, el cuello de botella de rendimiento del programa se puede analizar con mayor precisión utilizando el contador de seguimiento de rendimiento. Los desarrolladores pueden combinar diferentes indicadores de contador para identificar los cuellos de botella del sistema y mejorar el rendimiento del programa mediante la optimización del código y los algoritmos.

Los contadores de monitoreo de rendimiento comunes incluyen ciclos operativos de CPU (relojes), número de ejecuciones de instrucciones (instrucciones), tasa de aciertos de caché (aciertos de caché), latencia de acceso a la memoria (latencia de memoria), etc. Estos contadores generalmente se pueden obtener a través de herramientas dedicadas o interfaces de línea de comandos del sistema, como herramientas de rendimiento proporcionadas por sistemas Linux, Intel VTune, AMD CodeXL y otras herramientas de monitoreo de rendimiento.

Supongo que te gusta

Origin blog.csdn.net/qq_32378713/article/details/129811548
Recomendado
Clasificación