<< Chapter < Page Chapter >> Page >

Revisémoslas una por una.

Condicionales invariantes en el ciclo

El siguiente ciclo contiene una prueba invariante :


DO I=1,K IF (N .EQ. 0) THENA(I) = A(I) + B(I) * C ELSEA(I) = 0. ENDIFENDDO

“Invariante” significa que el resultado siempre es el mismo. Sin importar lo que suceda con las variables A , B , C , e I , el valor de N no cambia, ni tampoco lo hará el resultado del resto.

Usted puede reestructurar el ciclo, poniendo la prueba fuera y replicando el cuerpo del ciclo dos veces - una para el caso de que la prueba sea verdadera, y la otra para el resultado falso, como en el ejemplo siguiente:


IF (N .EQ. 0) THEN DO I=1,KA(I) = A(I) + B(I) * C ENDDOELSE DO I=1,KA(I) = 0 ENDDOENDIF

El efecto en el tiempo de ejecución es dramático. No sólo hemos eliminado K-1 copias de la prueba, también hemos asegurado que los cálculos en el centro del ciclo no tengan dependencias de control sobre la sentencia selectiva, y por tanto es mucho más fácil que el compilador lo ponga en una fila de espera.

Recordamos haber ayudado a alguien a optimizar un programa con ciclos que contenían condicionales similares. Comprobaban si debía imprimirse la salida del depurador adentro de cada iteración, o bien producir un ciclo altamente optimizable. No podemos culpar a la persona por no observar cuánto reducía esto la velocidad del programa. El rendimiento no era importante en ese momento. El programador sólo trataba de lograr que el código produjera respuestas correctas. Pero después, cuando comenzó a importar el rendimiento, limpiando condicionales invariantes fuimos capaces de acelerar el programa en un factor de 100.

Condicionales dependientes del indice del ciclo

Para los condicionales dependientes del índice del ciclo , la prueba es verdadera sólo para ciertos rangos de las variables usadas como índice del ciclo. Y no siempre es cierto o falso, como en otros condicionales que ya revisamos, pero cambia de acuerdo a un patrón apreciable, uno que puede usarse a nuestro favor. El siguiente ciclo tiene dos variables índice, I y J .


DO I=1,N DO J=1,NIF (J .LT. I) A(J,I) = A(J,I) + B(J,I) * CELSE A(J,I) = 0.0ENDIF ENDDOENDDO

Observe cómo la sentencia selectiva divide las iteraciones en dos conjuntos distintos: aquéllas en las cuáles es verdadero y aquéllas en las que es falso. Puede usted tomar ventaja de que tal cosa sea predecible, para reestructurar el bucle en varios bucles - cada uno personalizado para una partición distinta:


DO I=1,N DO J=1,I-1A(J,I) = A(J,I) + B(J,I) * C ENDDODO J=I,N A(J,I) = 0.0ENDDO ENDDO

La nueva versión resultará más rápida casi siempre, con la posible excepción del caso en que N tenga un valor pequeño, como 3, en cuyo caso hemos creado un mayor desorden. Pero aun en tal caso, el ciclo probablemente tendrá un impacto pequeño en el tiempo total de ejecución, del que hubiera tenido si se dejaba tal como está codificado.

Condicionales independientes del ciclo

Sería bueno que pudiera optimizar cada ciclo, particionándolo. Pero muy a menudo, el condicional no depende directamente del valor de las variables índice. Aunque una variable índice esté involucrada en el direccionamiento de un arreglo, no crea por adelantado un patrón reconocible - por lo menos no uno que pueda usted observar cuando está escribiendo el programa. He aquí uno de tales ciclos:

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