<< Chapter < Page Chapter >> Page >

Una empresa típica está llena de aterrorizantes ejemplos de sobrecarga. Digamos que un departamento ha preparado una pila de papelería, que debe completar otro departamento. ¿Qué debe usted de hacer para transferir tal trabajo? Primero, debe asegurarse que la parte que le tocó hacer esté completa; no puede pedirles que lo acepten si los materiales que requieren no están listos. Después, necesitará empaquetar los materiales - datos, formas, números de cuenta, etc. Y finalmente viene la transferencia oficial. Una vez que recibió lo que usted les envió, el otro departamento debe desempacarlo, hacer su trabajo, reempaquetarlo y enviarlo de vuelta.

Se malgasta una gran cantidad de tiempo moviendo trabajos entre departamentos. Por supuesto, si la sobrecarga es mínima comparada con la cantidad de trabajo útil que se hace, no hay gran problema. Pero pudiera ser más eficiente llevar a cabo los trabajos pequeños adentro del mismo departamento. Lo mismo puede afirmarse de la invocación de subrutinas y funciones. Si sólo entra y sale de los módulos muy de vez en cuando, la sobrecarga de guardar los valores en los registros y preparar la lista de argumentos no resultará significativa. Sin embargo, si está invocando repetidamente unas pocas subrutinas pequeñas, la sobrecarga puede mantenerlas siempre encabezando la lista del perfil. Puede que fuera mejor si el trabajo permaneciera donde está, en la subrutina emisora de la llamada.

Adicionalmente, los llamados a subrutinas inhiben la flexibilidad del compilador. Si se presenta la oportunidad, usted quiere que su compilador tenga la flexibilidad suficiente para entremezclar instrucciones que no son dependientes las unas de las otras. Y tales instrucciones se encuentran en ambas caras de un llamado a subrutina, en el invocador y en el invocado. Pero la oportunidad se pierde cuando el compilador no puede emparejarlas dentro de subrutinas y funciones. Y así, instrucciones que perfectamente pudieran solaparse, permanecen en sus respectivos lados de la barrera artificial.

Puede ser de ayuda que ilustremos el reto que representan las fronteras de las subrutinas mediante un ejemplo exagerado. Los siguientes bucles se ejecutan muy bien en una amplia variedad de procesadores:


DO I=1,N A(I) = A(I) + B(I) * CENDDO

El código de abajo realiza los mismos cálculos, pero observe qué hemos hecho:


DO I=1,N CALL MADD (A(I), B(I), C)ENDDO SUBROUTINE MADD (A,B,C)A = A + B * C RETURNEND

Cada iteración invoca a una subrutina para realizar una pequeña cantidad de trabajo, que antes estaba ubicado adentro del ciclo. Este es un ejemplo particularmente doloroso, porque involucra cálculos de punto flotante. La pérdida de paralelismo resultante, junto con la sobrecarga debida al llamado al procedimiento, puede producir código que se ejecuta 100 veces más lento. Recuerde, tales operaciones se colocan en líneas de espera, y toma cierta cantidad de tiempo "de recuperación" antes de que el rendimiento alcance siquiera una operación por ciclo de reloj. Si son pocas las operaciones de punto flotante que se realizan entre llamados a subrutinas, el tiempo gastado en llenar y vaciar las líneas de espera se volverá muy importante.

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Cómputo de alto rendimiento. OpenStax CNX. Sep 02, 2011 Download for free at http://cnx.org/content/col11356/1.2
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Cómputo de alto rendimiento' conversation and receive update notifications?

Ask