Instrucciones por ciclo

De Wikipedia, la enciclopedia libre
Saltar a: navegación, búsqueda

La unidad IPC o Instrucciones por ciclo (en inglés Instructions per cycle) indica la cantidad de instrucciones que un procesador ejecuta en un ciclo de reloj. En otras palabras, es un indicador más de rendimiento de un microprocesador. Otros factores de rendimiento son la frecuencia de reloj del microprocesador y la cantidad de instrucciones del programa. Por tanto tenemos que el rendimiento final de un microprocesador depende de tres factores: microarquitectura (IPC), tecnología (frecuencia de reloj) y compilador (instrucciones).

Las instrucciones de un procesador se suelen ejecutar dividas en varias etapas o fases. Cuando se tienen varias instrucciones en ejecución, una en cada etapa, en condiciones ideales se da el resultado aparente de obtener una instrucción por ciclo de reloj (IPC = 1), puesto que cuando una instrucción acaba su última fase, la instrucción siguiente entra en su última fase de manera que al siguiente ciclo acaba también, como si se tratara de la cadena de montaje de un coche.

El IPC normalmente trata de un valor medio, ya que la cantidad de instrucciones ejecutadas en un ciclo de reloj en la mayoría de microarquitectura de procesadores varía en función del programa ejecutado en el procesador. Sumas de números enteros, por ejemplo, pueden ejecutarse más rápidamente que sumas con números reales.

Los programas que se usan para medir el rendimiento de un procesador se llaman benchmark. Debido a la naturaleza del IPC y su valor en función del programa ejecutado, es importante seleccionar los programas (benchmarks) adecuados. Con la selección adecuada de benchmarks el IPC medio es más significativo y aproxima mejor el rendimiento en los entornos habituales de producción previstos. Por ello los benchmarks han de ser representativos de los programas que se van a ejecutar habitualmente con la microarquitectura del procesador medido. Por ejemplo, al diseñar un procesador multinúcleo los programas para medir su rendimiento no pueden consistir únicamente en programas con un sólo hilo de ejecución.

A la hora de medir el rendimiento de un procesador se calcula el tiempo que tarda en ejecutar un programa. Este tiempo se obtiene en base a la fórmula siguiente:

Si reordenamos las variables:

Donde N es el número de instrucciones -en código ensamblador compatible con el procesador- del programa (y sus algoritmos) y f es la frecuencia del procesador. es el recíproco del CPI o Ciclos por instrucción (en inglés Cycles per Instruction), usado también en la bibliografía especializada.

La N o número de instrucciones es un valor que depende del compilador empleado, puesto que el código fuente de los lenguajes de niveles superiores al del código máquina es transformado en éste mediante un compilador. En el caso de no usar un compilador, el valor de N dependerá de la pericia que tenga el programador en usar las instrucciones que ofrece la microarquitectura del procesador. Esto hace difícil la comparación directa entre dos modelos de procesador distintos, puesto que sin tener el código fuente disponible no es posible disponer de un programa en código máquina imparcial. El código fuente puede ser el escrito por un humano, ya sea en ensamblador o en un lenguaje de mayor nivel, o una representación intermedia (bytecode) como la usada por LLVM o Vulkan (SPIR-V[1]​).

Además, aún disponiendo del código fuente del programa, el compilador puede ser también parcial, como ya ocurriera antiguamente con el compilador de Intel. El Intel Compiler generaba binarios con unas instrucciones y planificación de las mismas que resultaban en un pobre rendimiento usando los procesadores de AMD y VIA Technologies para el mismo algoritmo.[2]​ Por tanto también es recomendable disponer del código fuente del compilador para poder comprobar que genera el mejor código posible para cada una de las microarquitecturas de las que obtener medidas de rendimiento. Entiéndase como mejor código posible la generación de un código máquina con instrucciones siguiendo una secuencia que no haga perder ciclos al procesador inútilmente cuando con otro orden de ejecución u otras instrucciones ofrecidas por su microarquitectura desperdiciaría menos ciclos, obteniendo un IPC más elevado.

Diseñar una microarquitectura para obtener un IPC elevado no es sencillo, y si los programas a ejecutar (incluidos los benchmarks) no disponen de código fuente y/o han sido programados para unas determinadas características de microarquitectura, las opciones de los arquitectos de computadores pueden verse seriamente limitadas. Éstos han de diseñar una microarquitectura para código máquina pensado para microarquitecturas de otros fabricantes. A su vez disminuye la innovación, puesto que todos los diseños de procesador tienden al mismo esquema con mínimas variaciones. Esto favorece al diseño del fabricante con mayor cuota de mercado, que siempre contará con la ventaja competitiva de ser el estándar de facto para el que todos los programadores crean y prueban sus programas.

Los desarrolladores de software tienen por tanto influencia en el IPC de una microarquitectura, puesto que el compilador que usen y el código que escriban puede favorecer a unos procesadores sobre otros. Bibliotecas de funciones y de tiempo de ejecución sirven para abstraerse de dichos detalles del hardware obteniendo un programa más neutral, relegando a dichas bibliotecas la optimización para cada una de las arquitecturas en las que se vaya a ejecutar el programa. Los compiladores incluyen bibliotecas de este tipo como pueden ser las funciones intrínsecas, OpenMP, OpenACC, OpenCL y CUDA. A su vez, con estas bibliotecas se crean abstracciones optimizadas para cada variante de arquitectura, para distintas generaciones de GPUs y CPUs. Bibliotecas de álgebra como GSL, [3]CuBLAS ,[4]clFFT y clBLAS, [5][6]ATLAS ,[7]LAPACK [8]​ y MAGMA [9]​ son algunos ejemplos de abstracciones con optimizaciones por microarquitectura que utilizan las bibliotecas que incluyen los compiladores. En el campo de los videojuegos la abstracción se correspondería con el motor gráfico, que a su vez utiliza bibliotecas como OpenGL, Vulkan o Direct3D distribuidas con el controlador de dispositivo del dispositivo gráfico, el cual incluye el compilador para generar el binario compatible con la GPU a partir del código shader del programador. La biblioteca de tiempo de ejecución Java distribuida con Android (Dalvik o ART, según versión de Android) abstrae las características del hardware y también del sistema operativo del dispositivo sobre el que se ejecuta la aplicación, lo que permite ejecutar las aplicaciones no sólo en dispositivos diferentes sino también en sistemas operativos diferentes.

Véase también[editar]


Enlaces externos[editar]

Referencias[editar]

  1. Khronos Group. «The first open standard intermediate language for parallel compute and graphics» (en inglés). Consultado el 9 de agosto de 2017. «For hardware vendors, ingesting SPIR-V eliminate the need to build a high-level language source compiler into device drivers, significantly reducing driver complexity, and will enable a broad range of language and framework front-ends to run on diverse hardware architectures. For developers, using SPIR-V means that kernel source code no longer has to be directly exposed, kernel load times can be accelerated and developers can choose the use of a common language front-end, improving kernel reliability and portability across multiple hardware implementations.» 
  2. Nick Farrell (4 de enero de 2010). «Intel's compiler cripples code on AMD and VIA chips» (en inglés). The Inquirer. Consultado el 7 de agosto de 2017. «But it also checks what instruction sets are supported by the CPU and it also checks the vendor ID string. If the string says 'GenuineIntel' then it uses the optimal code path. If the CPU is not from Intel then, in most cases, it will use the slowest version of the code it can find.» 
  3. «GSL: Using de library, alternative optimized functions» (en inglés). Consultado el 8 de agosto de 2017. «The main implementation of some functions in the library will not be optimal on all architectures. For example, there are several ways to compute a Gaussian random variate and their relative speeds are platform-dependent. In cases like this the library provides alternative implementations of these functions with the same interface. If you write your application using calls to the standard implementation you can select an alternative version later via a preprocessor definition. It is also possible to introduce your own optimized functions this way while retaining portability.» 
  4. NVIDIA. «Dense Linear Algebra on GPUs» (en inglés). Consultado el 8 de agosto de 2017. 
  5. AMD. «clFFT» (en inglés). Consultado el 8 de agosto de 2017. «clFFT provides a set of FFT routines that are optimized for AMD graphics processors, but also are functional across CPU and other compute devices.» 
  6. AMD. «clBLAS» (en inglés). Consultado el 8 de agosto de 2017. «The primary goal of clBLAS is to make it easier for developers to utilize the inherent performance and power efficiency benefits of heterogeneous computing.» 
  7. «Automatically Tuned Linear Algebra Software (ATLAS)» (en inglés). Consultado el 8 de agosto de 2017. 
  8. «Linear Algebra PACKage» (en inglés). Consultado el 8 de agosto de 2017. 
  9. «Matrix Algebra on GPU and Multicore Architectures» (en inglés). Consultado el 8 de agosto de 2017. «The MAGMA project aims to develop a dense linear algebra library similar to LAPACK but for heterogeneous/hybrid architectures, starting with current "Multicore+GPU" systems.»