Hola Desde el titular, ya entendiste de lo que voy a hablar. Habr谩 mucho hardcore:
discutiremos Java, C, C ++, ensamblador, un poco de Linux, un poco del n煤cleo del sistema operativo. Tambi茅n analizaremos un caso pr谩ctico, por lo que el art铆culo tendr谩 tres partes grandes (bastante voluminoso).

En el primero, intentaremos exprimir todo de los perfiladores existentes.
En la segunda parte, crearemos nuestro propio perfilador peque帽o, y en la tercera veremos c贸mo perfilar lo que no es habitual, porque las herramientas existentes no son muy adecuadas para esto. Si est谩s listo para seguir este camino, te estoy esperando debajo del corte :)
Contenido
Tiempo y medios de comprensi贸n - perfilador
Desde el punto de vista cotidiano, 1 segundo es muy peque帽o. Pero sabemos que 1 segundo es mil millones de nanosegundos. Y deje que tome aproximadamente 4 ciclos de procesador en solo 1 nanosegundo, en 1 segundo se hacen muchas cosas en la computadora que pueden mejorar o empeorar nuestras vidas.
Supongamos que estamos desarrollando una aplicaci贸n que en s铆 misma es lo suficientemente cr铆tica como para acelerar, y para algunos fragmentos de c贸digo esto es generalmente cr铆tico. Estas piezas se ejecutan, digamos, cientos de microsegundos, lo suficientemente r谩pido, pero [las
secciones del c贸digo ] afectan directamente el 茅xito de nuestra aplicaci贸n y la cantidad de dinero ganado o perdido. Por ejemplo
Al enviar 贸rdenes para concluir transacciones de intercambio, un retraso de 100 microsegundos puede costar al intercambio 1 mill贸n de rublos o m谩s en cada transacci贸n, que se completa con uno, no dos, o incluso no cien.
Y la
tarea se estableci贸 para m铆: por un lado, debe enviar todos los pedidos al mismo tiempo y, por otro lado, enviarlos de modo que la variaci贸n entre el primero y el 煤ltimo sea m铆nima. Es decir, era necesario perfilar una funci贸n que env铆a 贸rdenes al intercambio. Una tarea t铆pica, excepto por un peque帽o matiz: el tiempo de ejecuci贸n caracter铆stico de esta funci贸n es
significativamente menor que 100 渭s .
Pensemos en c贸mo perfilamos estos 100 渭s para comprender lo que est谩 sucediendo dentro.
驴Qu茅 tener en cuenta al elegir esta herramienta?
- La secci贸n de c贸digo que nos interesa rara vez se ejecuta, es decir, 100 microsegundos se ejecutan en alguna parte una vez por segundo. Y esto est谩 en el banco de pruebas, y en producci贸n a煤n menos.
- Ser谩 dif铆cil aislar este fragmento de c贸digo en un microbenchmark, ya que afecta a una parte importante del proyecto e incluso a la entrada / salida a trav茅s de la red.
- Y finalmente, lo m谩s importante, quiero que el perfil resultante corresponda con el comportamiento que tendr谩 en nuestros servidores de producci贸n.
驴C贸mo tomamos en cuenta todos estos matices y perfilamos correctamente el m茅todo de inter茅s?
Conceptualmente, todos los perfiladores se pueden dividir en dos grupos de perfiladores de
instrumentos o
muestreo . Consideremos cada grupo por separado.
Los perfiladores de herramientas aportan bastante sobrecarga porque modifican nuestro c贸digo de bytes e insertan un registro de temporizaci贸n en 茅l. De ah铆 el inconveniente clave de tales perfiladores: pueden afectar significativamente el c贸digo ejecutable. Como resultado, ser谩 dif铆cil decir cu谩nto coincide el perfil resultante con el comportamiento en los servidores de producci贸n: algunas optimizaciones pueden funcionar de manera diferente, algunas suceden y otras no. Quiz谩s, en otras escalas de tiempo - segundos, minutos, horas - obtendremos datos representativos. Pero en una escala de 100 渭s, la optimizaci贸n activada o fallida puede hacer que el perfil sea completamente no representativo. As铆 que echemos un vistazo m谩s de cerca a otro grupo de perfiladores.
Los perfiladores de muestreo contribuyen con una sobrecarga m铆nima o moderada. Estas herramientas no afectan directamente el c贸digo ejecutable, y su uso requiere un poco m谩s de atenci贸n por su parte. Por lo tanto, nos detendremos en los perfiladores de muestreo. Veamos qu茅 datos y de qu茅 forma recibiremos de ellos.
驴C贸mo funcionan los perfiladores de muestreo?
Para comprender c贸mo funciona un generador de perfiles de muestreo, considere el siguiente ejemplo: el m茅todo
sendToMoex llama a otros m茅todos. Buscamos:
void sendToMoex() { a.qqq(); b.doo(); c.ccc() } void doo() { da(); db(); }
Si controlamos el estado de la pila de llamadas en el momento de la ejecuci贸n de esta secci贸n del programa y la registramos peri贸dicamente, obtendremos informaci贸n aproximadamente de la siguiente forma:

Este es un conjunto de pilas de llamadas. Suponiendo que las muestras se distribuyen uniformemente, el n煤mero de pilas id茅nticas indica el tiempo de ejecuci贸n relativo del m茅todo que est谩 en la parte superior de la pila.
En este ejemplo, el m茅todo Da se ejecut贸 tanto como el m茅todo C.ccc, y esto es 2 veces m谩s que el m茅todo Db. Sin embargo, la suposici贸n de que la distribuci贸n de las muestras incluso puede no ser completamente correcta, y entonces la estimaci贸n del tiempo de ejecuci贸n ser谩 incorrecta.
驴Con qu茅 frecuencia necesitamos tomar muestras?
Supongamos que queremos tomar 1000 muestras en 100 microsegundos para comprender lo que se reproduce dentro. Luego, calculamos con una proporci贸n simple que si necesitamos hacer 1000 muestras en 100 渭s, entonces son 10 millones de muestras en 1 segundo o 10,000,000 muestras / s.

Si tomamos muestras a esa velocidad, en una ejecuci贸n del c贸digo recolectaremos 1000 muestras, agregaremos y entenderemos lo que funcion贸 r谩pida o lentamente. Despu茅s de eso, analizaremos el rendimiento y ajustaremos el c贸digo.
Sin embargo, una frecuencia de 10 millones de muestras por segundo es mucha. 驴Y si no logramos alcanzar esa velocidad de creaci贸n de perfiles desde el principio? Supongamos que recolectamos 10 渭s solo 10 muestras, no 1000. En este caso, tenemos que esperar a la pr贸xima ejecuci贸n del c贸digo perfilado, que suceder谩 despu茅s de 1 segundo (despu茅s de todo, el c贸digo perfilado se ejecuta una vez por segundo). Entonces recolectaremos 10 muestras m谩s. Como se distribuyen uniformemente con nosotros, se pueden combinar en un conjunto com煤n. Es suficiente esperar hasta que el c贸digo perfilado se ejecute 1000/10 = 100 veces, y recopilaremos las 1000 muestras requeridas (10 muestras cada una de 100 veces).
Elige un perfilador
Armados con este conocimiento te贸rico, pasemos a la pr谩ctica.
Tome
Async-profiler. Una gran herramienta (utiliza la llamada de m谩quina virtual AsyncGetCallTrace) que recopila la pila de llamadas seg煤n las instrucciones del c贸digo de bytes de la m谩quina virtual Java. La tasa de muestreo nativa del perfilador as铆ncrono es de
1000 muestras por segundo .
Resolveremos una proporci贸n simple: 10,000,000 muestras / seg - 1 segundo, 1000 muestras / seg - X segundos.
Obtenemos que a la frecuencia de muestreo est谩ndar de async-profiler, la creaci贸n de perfiles llevar谩 aproximadamente 3 horas. Esto es mucho tiempo Idealmente, quiero ensamblar el perfil lo m谩s r谩pido posible, justo a la velocidad superluminal.
Intentemos overclockear
Async-profiler . Para hacer esto, en el archivo L茅ame, encontramos la bandera
-i
, que establece el intervalo de muestreo. Intentemos establecer el indicador
-i1
(1 nanosegundo), o
-i0
en general, para que el generador de muestras
-i0
sin parar. Obtuve una frecuencia de aproximadamente 2.5 mil muestras por segundo. En este caso, la duraci贸n total del perfil ser谩 de aproximadamente 1 hora. Por supuesto, no 3 horas, pero tampoco muy r谩pido. Parece que para alcanzar las velocidades de perfilado requeridas, debe hacer algo cualitativamente diferente para alcanzar un nuevo nivel.
Para lograr frecuencias significativamente m谩s altas, tendr谩 que abandonar la llamada AsyncGetCallTrace y usar
perf , el generador de perfiles de Linux a tiempo completo que se encuentra en cada distribuci贸n de Linux. Sin embargo, perf no sabe nada sobre Java, y todav铆a tenemos que entrenar a perf para trabajar con Java. Mientras tanto, intentemos ejecutar perf de esta manera aterradora:
$ perf record 鈥揊 10000 -p PID -g -- sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: .. 0.215 MB perf.data (4032 samples) ]
M谩s sobre notaci贸n- perf record significa que queremos grabar un perfil.
- La bandera
-F
y el argumento 10,000 son la frecuencia de muestreo. - El indicador
-p
indica que queremos perfilar solo el PID espec铆fico de nuestro proceso Java. - La bandera
-g
es responsable de recoger las pilas de llamadas. - Finalmente, con el sue帽o 1, limitamos la entrada del perfil a 1 segundo.
驴Por qu茅 necesitamos recolectar pilas de llamadas? Perfilamos todo en una fila, y luego de los datos recopilados extraemos la parte que nos interesa (el m茅todo responsable de la formaci贸n y el env铆o de pedidos). El marcador de que la muestra recopilada pertenece a los datos que nos interesan es la presencia del marco de pila de la
llamada al m茅todo
sendToMoex .
Aprenda perf para construir un perfil de aplicaci贸n Java.
Ejecutamos el comando perf record ..., esperamos 1 segundo y ejecutamos el script perf para ver qu茅 se ha perfilado. Y veremos algo no muy claro:
$ perf script java 8079 2008793.746571: 3745505 cycles:uppp: 7fa1e88b53f8 [unknown] (/tmp/perf-11038.map) java 8079 2008793.747565: 3728336 cycles:uppp: 7fa1e88b5372 [unknown] (/tmp/perf-11038.map) java 8079 2008793.748613: 3731147 cycles:uppp: 7fa1e88b53ef [unknown] (/tmp/perf-11038.map)
Parece que son direcciones, pero no hay nombres de m茅todos Java. Por lo tanto, debe ense帽ar a perf para que coincida con estas direcciones con los nombres de los m茅todos.
En el mundo de C y C ++, la llamada informaci贸n de depuraci贸n se usa para unir direcciones y nombres de funciones. Una correspondencia se almacena en una secci贸n especial del archivo ejecutable: un m茅todo se encuentra en dichas direcciones, otro m茅todo se encuentra en otras direcciones. Perf extrae esta informaci贸n y hace un mapeo.
Obviamente, el compilador JIT de m谩quina virtual no genera informaci贸n de depuraci贸n en este formato. Todav铆a tenemos otra manera: escribir datos sobre la correspondencia de direcciones y nombres de m茅todos en un archivo especial de perf-map, que perf tratar谩 como una adici贸n a la informaci贸n de depuraci贸n le铆da. Este archivo de perf-map debe estar en la carpeta tmp y tener la siguiente estructura de datos:
La primera columna es la direcci贸n del comienzo del c贸digo del m茅todo, la segunda es su longitud, la tercera columna es el nombre del m茅todo.
Entonces, necesitamos generar un archivo similar. Obviamente, no podremos hacer esto manualmente (c贸mo sabemos en qu茅 direcciones colocar谩 el c贸digo el compilador JIT), por lo que utilizaremos el script create-java-perf-map.sh del proyecto perf-map-agent, pas谩ndole el PID de nuestro proceso Java . El archivo est谩 listo, verifique su contenido, ejecute perf-script nuevamente.
$ perf script java 8080 1895245.867498: cycles:uppp: 7fb2dd10f527 Loop3.doRecursiveCall (/tmp/perf-8079.map) java 8080 1895245.868176: 2127960 cycles:uppp: 7fb2dd10f57f Loop3.doRecursiveCall (/tmp/perf-8079.map) java 8080 1895245.868737: 1959990 cycles:uppp: 7fb2dd10f627 Loop3.doRecursiveCall (/tmp/perf-8079.map)
Voila! 隆Vemos los nombres de los m茅todos de Java! Lo que acaba de suceder: le ense帽amos al perfilador de perf, que no sabe nada sobre Java, a perfilar una aplicaci贸n Java normal y ver los m茅todos java m谩s populares de esta aplicaci贸n.
Sin embargo, para analizar el rendimiento de la parte del programa que estamos interrogando, no tenemos suficiente pila de llamadas para filtrar los datos de inter茅s de todas las muestras recopiladas.
驴C贸mo obtener una pila de llamadas?Ahora necesita hacer algo m谩s con perf o una m谩quina virtual para obtener pilas de llamadas. Para comprender lo que hay que hacer, demos un paso atr谩s y veamos c贸mo funciona la pila en general. Imagine que tenemos tres funciones f1, f2, f3. Adem谩s, f1 llama a f2 y f2 llama a f3.
void f1() { f2(); } void f2() { f3(); } void f3() { ... }
En el momento en que
f3
ejecuta la funci贸n
f3
, veamos en qu茅 estado se encuentra la pila. Vemos el registro
rsp
, que apunta a la parte superior de la pila. Tambi茅n sabemos que la pila tiene la direcci贸n del marco de pila anterior. 驴Y c贸mo puedo obtener una pila de llamadas?
Si de alguna manera pudi茅ramos obtener la direcci贸n de esta 谩rea, podr铆amos imaginar la pila como una lista simplemente conectada y comprender la secuencia de llamadas que nos llevaron al punto de ejecuci贸n actual.
驴Qu茅 necesitamos para esto? Necesitamos un registro rbp adicional que apunte al 谩rea amarilla. Resulta que el registro rbp permite que perf obtenga la pila de llamadas, para comprender la secuencia que nos llev贸 al punto actual. Recomiendo leer estos detalles en la
interfaz binaria de la aplicaci贸n System V. Describe c贸mo se llaman los m茅todos en Linux.

Entendimos cu谩l es nuestro problema. Necesitamos forzar a la m谩quina virtual a usar el registro rbp para su prop贸sito original, como un puntero al comienzo del marco de la pila. As铆 es como el compilador JIT debe usar el registro rbp. Hay una bandera PreserveFramePointer en la m谩quina virtual para esto. Cuando pasamos este indicador a la m谩quina virtual, la m谩quina virtual comenzar谩 a usar el registro rbp para su prop贸sito tradicional. Y luego Perf puede hacer girar la pila. Y obtenemos una pila de llamadas real en el perfil. La bandera fue aportada por el famoso Brendan Gregg en solo JDK8u60.
Comenzamos la m谩quina virtual con una nueva bandera. Ejecute
create-java-perf-map
, luego
perf record
y
perf script
. Ahora podemos construir un perfil preciso con pilas de llamadas:
$ perf script java 18657 1901247.601878: 979583 cycles:uppp: 7fbfd1101edc Loop3.doRecursiveCall (...) 7fbfd1101edc Loop3.doRecursiveCall (...) 7fbfd1101edc Loop3.doRecursiveCall (...) 7fbfd1101edc Loop3.doRecursiveCall (...) 7f285d007b10 Interpreter (...) 7f285d0004e7 call_stub (...) 67d0db [unknown] (... libjvm.so) ... 708c start_thread (... libpthread-2.26.so)
Ense帽amos perf profiler, incluido con la mayor铆a de las distribuciones de Linux, para trabajar con aplicaciones Java. Por lo tanto, ahora podemos ver no solo las secciones activas del c贸digo, sino tambi茅n la secuencia de llamadas que condujeron a la zona activa actual. Un gran logro, dado que el perfilador perf no sabe nada sobre Java. 隆Acabamos de ense帽arle a perf todo esto!
Aumentar la tasa de muestreo de perf
Intentemos overclockear perf a 10 millones de muestras por segundo. Ahora tenemos una frecuencia significativamente menor.
Para automatizar todas las tareas que acabamos de hacer, puede usar el script
perf-java-record-stack
del proyecto perf-map-agent. Tiene un l谩piz maravilloso: la variable de entorno
perf_record-freq
, con la que puede establecer la frecuencia de muestreo. Primero, configuremos 100 mil muestras por segundo e intentemos ejecutar. Aparece un terrible mensaje en la consola que indica que hemos excedido la frecuencia de muestreo m谩xima permitida:
$ PERF_RECORD_FREQ=100000 ./bin/perf-java-record-stack PID ... Maximum frequency rate (30000) reached. Please use -F freq option with lower value or consider tweaking /proc/sys/kernel/perf_event_max_sample_rate. ...
En mi caso, el l铆mite era de 30 mil muestras por segundo. Perf dice inmediatamente qu茅 argumento del kernel debe corregirse, lo que haremos utilizando echo sudo tee para el archivo deseado o directamente a trav茅s de
sysctl
. Entonces
$ echo '1000000' | sudo tee /proc/sys/kernel/perf_event_max_sample_rate
m谩s o menos:
$ sudo sysctl kernel.perf_event_max_sample_rate=1000000
Ahora le estamos diciendo al n煤cleo que el l铆mite superior de la frecuencia es ahora de 1 mill贸n de muestras por segundo. Comenzamos el perfilador nuevamente e indicamos la frecuencia de 200 mil muestras por segundo. El generador de perfiles funcionar谩 durante 15 segundos y nos dar谩 1 mill贸n de muestras. Todo parece estar bien. Al menos no hay mensajes de error formidables. Pero, 驴qu茅 frecuencia obtuvimos realmente? Resulta que solo 70 mil muestras por segundo. 驴Qu茅 sali贸 mal?
Veamos el resultado del
dmesg
:
[84430.412898] perf: interrupt took too long (1783 > 200), lowering kernel.perf_event_max_sample_rate to 89700 ... [84431.618452] perf: interrupt took too long (2229 > 2228), lowering kernel.perf_event_max_sample_rate to 71700
Esta es la salida del kernel de Linux. Se dio cuenta de que tomamos muestras con demasiada frecuencia, y lleva demasiado tiempo, por lo que el n煤cleo reduce la frecuencia. Resulta que necesitamos desenroscar otro controlador en el kernel: se llama
kernel.perf_cpu_time_max_percent
y controla la cantidad de tiempo que el kernel puede pasar en las interrupciones de perf.
Ordenaremos una frecuencia de muestreo de 200 mil muestras por segundo. Y despu茅s de 15 segundos obtenemos 3 millones de muestras, 200 mil muestras por segundo.
$ PERF_RECORD_FREQ=200000 ./bin/perf-java-record-stack PID Recording events for 15 seconds ... ... [ perf record: Captured ... (2.961.252 samples) ]
Ahora veamos el perfil. Ejecutar
perf script
:
$ perf script ... java ... native_write_msr (/.../vmlinux) java ... Loop2.main (/tmp/perf-29621.map) java ... native_write_msr (/.../vmlinux) ...
Vemos funciones extra帽as y el m贸dulo ejecutable vmlinux: el kernel de Linux. Este definitivamente no es nuestro c贸digo. Que paso La frecuencia result贸 ser tan alta que el c贸digo del n煤cleo comenz贸 a caer en las muestras. Es decir, cuanto mayor sea la frecuencia, m谩s muestras habr谩 que no est茅n relacionadas con nuestro c贸digo, sino con el kernel de Linux.
Callej贸n sin salida.
Utilizamos (expl铆citamente) eventos de hardware PMU / PEBS
Luego decid铆 intentar usar la tecnolog铆a de hardware PMU / PEBS: unidad de monitoreo de rendimiento, muestreo basado en eventos precisos. Le permite recibir notificaciones de que se ha producido un evento varias veces. Esto se llama un "per铆odo". Por ejemplo, podemos recibir notificaciones sobre la ejecuci贸n por parte del procesador de cada vig茅sima instrucci贸n. Veamos un ejemplo. Deje que la instrucci贸n xor se ejecute ahora, y el contador PMU obtiene el valor 18; luego viene la instrucci贸n mov: el contador es 19; y en la siguiente instrucci贸n,
agregue% r14,% r13 , PMU se mostrar谩 como "
activo ".
Luego comienza un nuevo ciclo: se ejecuta
inc
; la PMU se restablece a 1. Se realizan algunas iteraciones m谩s del ciclo. Al final, nos detenemos en la instrucci贸n
mov
, la PMU se ajusta a 19. La siguiente instrucci贸n add, y nuevamente la marcamos como hot. Ver el listado:
mov aaa, bbbb xor %rdx, %rdx L_START: mov $0x0(%rbx, %rdx),%r14 add %r14, %r13 ; (PMU "") cmp %rdx,100000000 jne L_START
驴No te das cuenta de las rarezas? Un ciclo de cinco instrucciones, pero cada vez que marcamos la misma instrucci贸n como hot. Obviamente, esto no es cierto: todas las instrucciones son "calientes". Tambi茅n pasan tiempo, y marcamos solo uno. El hecho es que entre el per铆odo y el contador del n煤mero de instrucciones en la iteraci贸n tenemos un factor com煤n 4. Resulta que cada cuarta iteraci贸n marcaremos la misma instrucci贸n como "activa". Para evitar este comportamiento, debe elegir un n煤mero como un per铆odo en el que se minimiza la probabilidad de un divisor com煤n entre el n煤mero de iteraciones en el bucle y el contador. Idealmente, el per铆odo deber铆a ser primo, es decir compartir solo en usted y en la unidad. Para el ejemplo anterior: debe elegir un per铆odo igual a 23. Luego, marcar铆amos de manera uniforme todas las instrucciones de este ciclo como "activas".
La tecnolog铆a PMU / PEBS ha recibido soporte en su forma moderna desde al menos 2009, es decir, est谩 disponible en casi cualquier computadora. Para aplicarlo expl铆citamente, modifiquemos el script
perf-java-record-stack
. Reemplace el indicador
-F
con
-e
, que especifica expl铆citamente el uso de PMU / PEBS.
... sudo perf record -F $PERF_RECORD_FREQ ... ...
Transformando el gui贸n:
... sudo perf record -e cycles 鈥揷 10007 ... ...
Ya sabes qu茅 propiedades debe tener un per铆odo: necesitamos un n煤mero primo. Para nuestro caso, ser谩 el per铆odo 10007.
Lanzamos el script modificado perf-java-record-stack y en 15 segundos recibimos 4.5 millones de muestras, esto es casi 300 mil por segundo, una muestra cada 3 渭s. Es decir, para una ejecuci贸n de nuestro c贸digo perfilado, por 100 渭s recolectaremos 33 muestras. A esta frecuencia, el tiempo total de recopilaci贸n del perfil es de solo 30 segundos. 隆Ni siquiera tomes una taza de caf茅! En realidad, todo es un poco m谩s complicado. 驴Qu茅 sucede si nuestro c贸digo comienza a ejecutarse no una vez por segundo, sino una vez cada 5 segundos? Luego, la duraci贸n de la creaci贸n de perfiles crecer谩 hasta 2,5 minutos, lo que tambi茅n es un resultado bastante decente.
Por lo tanto, en 30 segundos puede obtener un perfil que cubra completamente todas nuestras necesidades de investigaci贸n. Victoria
Pero la sensaci贸n de alg煤n truco sucio no me dej贸. Volvamos a la situaci贸n en la que nuestro c贸digo se ejecuta cada 5 segundos. Luego, la elaboraci贸n de perfiles llevar谩 150 segundos, tiempo durante el cual recolectaremos alrededor de 45 millones de muestras. De estos, solo necesitamos 1000, es decir, 0.002% de los datos recopilados. Todo lo dem谩s es basura, lo que ralentiza el trabajo de otras herramientas y agrega gastos generales. S铆, el problema est谩 resuelto, pero est谩 resuelto en la frente, fuerza sucia y contundente.
Y esa noche, cuando obtuve un perfil tan detallado con la ayuda de perf, tuve un sue帽o. Iba a casa del trabajo y pensaba, pero ser铆a bueno si el hierro pudiera ensamblar el perfil en s铆 mismo e incluso con la precisi贸n de las microestructuras y los microsegundos, y solo analizar铆amos los resultados. 驴Se har谩 realidad mi sue帽o? Que piensas
Breve resumen:
- Para crear un perfil de una aplicaci贸n Java usando perf, necesita generar un archivo con informaci贸n sobre s铆mbolos usando scripts del proyecto perf-map-agent
- Para recopilar informaci贸n no solo sobre secciones activas de c贸digo, sino tambi茅n pilas, debe ejecutar una m谩quina virtual con el indicador -XX: + PreserveFramePointer
- Si desea aumentar la frecuencia de muestreo, debe prestar atenci贸n a sysctl'i y kernel.perf_cpu_time_max_percent y kernel.perf_event_max_sample_rate.
- Si las muestras del kernel que no est谩n relacionadas con la aplicaci贸n comenzaron a ingresar al perfil, debe pensar en especificar expl铆citamente el per铆odo PMU / PEBS.
Este art铆culo (y sus partes posteriores) es una transcripci贸n del informe, adaptado en forma de texto. Si desea no solo leer, sino tambi茅n escuchar sobre la creaci贸n de perfiles, una
referencia a la presentaci贸n.