Sistemas operativos modernos
Un lema muy válido en relación con la optimización del desempeño es Lo bastante bueno es bastante bueno. Esto quiere decir que, una vez que el desempeño ha alcanzado un nivel razonable, lo más se guro es que el esfuerzo y la complejidad necesarios para exprimir los últimos puntos porcen tuales de desempeño no valgan la pena. Si el algoritmo de calendarización es razonablemente equitativo y mantiene a la CPU ocupada 90% del tiempo, está cumpliendo con su trabajo. Es probable que sea una mala idea concebir un algoritmo mucho más complejo que sea 5%. Por lo mismo, si la tasa de paginación es lo bastante baja como para no convertirse en un cuello de botella, por lo general no valdrá la pena hacer malabarismos para tratar de obtener un desem peño óptimo de la paginación. Es más importante evitar desastres que obtener un desempeño óptimo, sobre todo considerando que lo que es óptimo con una carga podría no ser óptimo con otra. 12.4.3 Equilibrio espacio-tiempo Un método general para mejorar el desempeño es sacrificar tiempo a cambio de espacio. En las ciencias de la computación, muchas veces hay que tomar decisiones entre un algoritmo que consume poca memoria pero es lento y uno que consume mucha memoria pero es más rápido. Al efectuar una optimización importante, conviene buscar algoritmos que ganen velocidad ocu pando más memoria o, por otro lado, que ahorren memoria escasa realizando más cálculos. Una técnica que suele ser útil es sustituir procedimientos pequeños por macros. El uso de una macro elimina el gasto adicional que normalmente conlleva una llamada a procedimien to. La ganancia es más importante aun si la llamada se efectúa dentro de un ciclo. Por ejem plo, supongamos que usamos mapas de bits para llevar el control de los recursos y que con frecuencia necesitamos saber cuántas unidades están libres en alguna porción del mapa de bits. Para ello necesitamos un procedimiento, bit_count, que cuente el número de bits 1 en un byte. El procedimiento directo se da en la figura l2-6a. En cada iteración del ciclo se cuenta un bit del byte. Este procedimiento tiene dos causas de ineficiencia. La primera es que hay que invocarlo, asignarle espacio y luego volver de él. Toda llamada a procedimiento fiene este gasto adicional. La segunda es que contiene un ciclo, y los ciclos siempre implican algún gasto suplementario. Un método completamente distinto consiste en ufifizar la macro de ia figura 12-6b. Se tra ta de una expresión desarrollada en línea que calcula la suma de los bits desplazando de mane ra sucesiva el argumento, enmascarando todo excepto el bit de orden bajo y sumando los ocho términos. La macro dista mucho de ser una obra de arte, pero sólo aparece una vez en el códi go. Cuando se invoca la macro, digamos con sum=bit_count(table[i]): la llamada a la macro se ve idéntica a la llamada al procedimiento. Así, fuera de una definición poco elegante, el código no se ve peor en el caso de la macro que en el del procedimiento, pero
RkJQdWJsaXNoZXIy MjI4NDcx