Cómo asignar un programa a un núcleo del CPU usando taskset

En la medida en que los procesadores multi-núcleo se tornan cada vez más comunes tanto en servidores como en latops o PCs de escritorio, e incluso hasta en dispositivos móviles, cada vez son más las aplicaciones optimizadas para este tipo de sistemas. No obstante, a veces puede resultar útil vincular un programa o proceso a uno o varios núcleos específicos. Veamos cómo conseguirlo…

Instalar taskset

La herramienta taskset forma parte del paquete “util-linux”. La mayor parte de las distribuciones Linux vienen con el paquete pre-instalado de forma predeterminada. En caso de que taskset no esté disponible, es posible instalarlo de la siguiente manera:

En Debian/Ubuntu y derivados:

sudo apt-get install util-linux

En Fedora y derivados:

sudo yum install util-linux

Ver la afinidad de CPU (CPU affinity) de un proceso en ejecución

Para recuperar la información de afinidad de CPU de un proceso, hay que utilizar el siguiente formato:

taskset -p PID

Por ejemplo, para comprobar la afinidad de la CPU de un proceso con PID 2915:

taskset -p 2915

Devuelve el resultado:

pid 2915's current affinity mask: ff

taskset devuelve la afinidad de CPU actual en un formato de máscara de bits hexadecimal. En el ejemplo, la afinidad (representada en una máscara de bits hexadecimal) corresponde a “11111111” en formato binario, lo que significa que el proceso puede ejecutarse en cualquiera de los ocho núcleos de CPU diferentes (de 0 a 7).

El bit más bajo en una máscara de bits hexadecimal corresponde al núcleo ID 0, el segundo bit más bajo desde la derecha al núcleo ID 1, el tercer bit más bajo al núcleo ID 2, etc. Así, por ejemplo, una afinidad de CPU “0x11” representa a los núcleos ID 0 y 4.

taskset puede mostrar la afinidad de CPU como una lista de procesadores en lugar de una máscara de bits, lo cual es mucho más fácil de leer. Para utilizar este formato, hay que ejecutar taskset con la opción “-c”. Por ejemplo:

taskset -cp 2915

Devuelve el resultado:

pid 2915's current affinity list: 0-7

Obligar a un proceso a que se ejecute en un núcleo específico

Utilizando taskset, se puede asignar un proceso en ejecución a un núcleo específico de la CPU. Para ello, hay que utilizar el siguiente formato:

taskset -p COREMASK PID
taskset -cp CORE-LIST PID

Por ejemplo, para asignar un proceso a los núcleos 0 y 4, hay que ejecutar:

taskset -p 0x11 9030

Lo que devuelve el resultado:

pid 9030's current affinity mask: ff
pid 9030's new affinity mask: 11

En forma equivalente, se puede ejecutar:

taskset -cp 0,4 9030

Con la opción “-c”, se puede especificar una lista de IDs de núcleo numéricos, separados por comas, o incluso se pueden incluir rangos (por ejemplo, 0,2,5,6-10).

Lanzar un programa utilizando un núcleo específico

taskset también permite lanzar un nuevo programa utilizando una serie de núcleos específicos. Para ello, hay que utilizarlo con el siguiente formato:

taskset COREMASK EJECUTABLE

Por ejemplo, para poner en marcha el programa VLC en el núcleo ID 0 de la CPU, hay que utilizar el siguiente comando:

taskset -c 0 vlc

Dedicar un núcleo únicamente a un programa en particular

Si bien taskset permite asignar a un programa a un núcleo en particular, eso no significa que no haya otros programas o procesos que hagan uso del mismo. Para evitar esto y dedicar un núcleo entero a un programa en particular, hay que utilizar el parámetro del kernel “isolcpus”, que permite reservar un núcleo durante el arranque.

Para ello, hay que añadir el parámetro “isolcpus = ” en la línea del kernel en GRUB. Por ejemplo, para reservar los núcleos ID 0 y 1, hay que añadir “isolcpus = 0,1”.

Una vez hecho esto, el planificador de Linux no asignará ningún proceso regular al núcleo reservado, a menos que sea específicamente asignado con taskset.

Fuente: xmodulo & taskset man pages.


11 comentarios

  1.   petercheco dijo

    Buen post :).

  2.   Luis dijo

    Buen post pero sin animos de trollear…

    ¿Qué utilidad tiene asignar un programa a un núcleo específico???

    Quiero decir; si tienes un equipo con 12 núcleos lo lógico sería que determinado programa se ejecutase haciendo uso de esos 12 núcleos y no limitarlo ya que de esa forma obtenemos el mayor rendimiento posible.

    A lo que sí le veo utilidad es la opción que nos permite que a cierto núcleo no se le asigne ningún proceso dejando su uso exclusivo a determinado programa.

    1.    jvk85321 dijo

      Tiene logica lo que mencionas, al dejar que el planificador use todos los cores se balancea mejor los recursos, pero a veces se requiere un nucleo de dedicacion exclusiva, como correr una maquina virtual con una tarea especifica, el rendimiento de esa maquina mejora sustancialmente al no haber mas procesos corriendo en el nucleo asignado.

      atte
      jvk85321

      1.    usemoslinux dijo

        Exacto! Gracias, jvk! 🙂

      2.    lf dijo

        Pero cuando estas creando la maquina virtual te pide que elijas la cantidad de CPU asignadas… de que sirve elegir este valor si al final el sistema operativo omite esto y la ejecuta en todas las CPU… Por ahi el ejemplo no es el mejor…

        Para hacer funcionar Flash sobre Windows 8.1 x64, AMD y Firefox se recomendaba elegir que Flash se ejecute solo en un CPU, sin embargo a mi no me funciono. Seria comodo tambien que lo agreguen (si es que no esta) a los administradores de tareas de los distintos DE, o al menos al de KDE.

      3.    lf dijo

        ah no había entendido el final del comentario… Pero para eso habría que banear a todos los procesos sobre el CPU que ejecuta la maquina virtual. O bien asignarlos a otros CPU. Interesante y muy buen comentario.

    2.    Fernando dijo

      Sirve para crear supercomputadoras genios

  3.   Luis dijo

    Entendido.

    Gracias por la aclaración.

  4.   Teck dijo

    Al reservar un núcleo para un programa especifico que ocurre con los hilos de ejecución?, en el caso que lo haga con un nucleo con HT reserva 2 hilos de ejecucion para el programa??.

  5.   Swicher dijo

    Quizás este comando no parezca de mucha utilidad en computadoras con varios núcleos, pero para los que tenemos un Dual Core es bastante practico. Así por ejemplo, tengo un juego que cuando lo abro me usa todos los núcleos del procesador y si también tengo otros programas que necesitan la CPU (como alguna búsqueda con grep en archivos grandes) entonces el sistema se enlentece. La solución es tan simple como limitar el juego a que solo use uno de los núcleos.
    También estoy de acuerdo con lf, realmente deberían integrar esto en los administradores de tareas (de los que he probado hasta ahora en Gentoo, creo que ninguno lo tiene), en especial cuando en Windows es algo que existe desde XP (botón derecho sobre un proceso > “Establecer afinidad…”) pero hace tiempo encontré el siguiente script que convierte a taskset en algo un poco mas intuitivo (originalmente lo publicaron aquí e incluso se muestran algunos casos en los que resulta necesario gestionar el uso de los núcleos):
    #!/bin/bash
    read -p 'Ingrese el ID del proceso en cuestión: ' ID
    read -p 'Ingrese la lista de procesadores separados por comas: ' P
    echo 'Su ID es '$ID' y los procesadores son '$P
    sudo taskset -p -c $P $ID
    read -p 'Listo, presione enter para finalizar' P

    Con algunas modificaciones se le podría indicar el nombre del proceso en lugar del PID (o que acepte ambos y que decida cuando ese parámetro es una cosa o la otra).

  6.   jorss dijo

    no hay una interfax grafica para taskset para los nuevos usuario les seria de agrado

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.