Al hacer la transición a SAS© Viya™, una pregunta frecuente entre los desarrolladores es: ¿por qué un código parece mucho más rápido en CAS, mientras que en otros casos la ganancia es menos obvia? Más importante aún, ¿por qué ciertos códigos lógicos, que funcionaban perfectamente en SAS© 9, producen resultados diferentes en CAS?
Este artículo explora los mecanismos subyacentes que distinguen el motor tradicional SAS© (SMP) del motor distribuido CAS (MPP), centrándose en el DATA step.
1. La Velocidad: In-Memory y E/S de Disco
Una de las ventajas más obvias de CAS es el procesamiento en memoria (In-Memory).
SAS© Clásico (SAS© 9): El procesamiento a menudo implica lecturas y escrituras en el disco duro. Aunque el procesador sea rápido, el cuello de botella suele ser la etapa de escritura (I/O).
CAS: Los datos residen en la memoria RAM. La eliminación de los pasos de escritura en disco acelera significativamente el tiempo de ejecución global.
Esto a menudo explica por qué un código que genera grandes volúmenes de datos (como un bucle que crea millones de líneas con cálculos) se ejecuta más rápido en CAS: el tiempo ganado no proviene únicamente del cálculo de la CPU, sino de la ausencia de escritura física en el disco.
2. La Trampa del "Single Thread" (Monohilo)
Sin embargo, es crucial notar que CAS no es mágico. No todo se ejecuta automáticamente en paralelo.
Tomemos el ejemplo de un DATA step que genera datos sin tabla de entrada (por ejemplo, un bucle DO de 1 a 5 millones para crear datos simulados):
En este caso específico, CAS ejecutará este código en un solo hilo (monohilo). El registro (log) mostrará una nota explícita:
NOTE: The DATA step has no input data set and will run in a single thread.
En un escenario puramente monohilo, a veces el motor SAS© 9 clásico es más eficiente e incluso más rápido que CAS, ya que tiene menos "sobrecarga" de gestión del sistema que el motor distribuido. El poder de CAS reside en la distribución; sin distribución, esta ganancia puede anularse.
3. El Cambio de Paradigma: Paralelismo y Particionamiento
La verdadera diferencia arquitectónica aparece cuando el DATA step lee una tabla distribuida. CAS divide los datos en bloques y los reparte entre varios hilos (y potencialmente varios nodos/máquinas).
Esto introduce cambios de comportamiento importantes para algunas instrucciones históricas de SAS©.
En SAS© 9, la instrucción RETAIN conserva un valor de una observación a la siguiente. En CAS, esta conservación se realiza dentro del mismo hilo. Un valor retenido en el "Hilo 1" no es visible para el "Hilo 2".
La trampa de END=EOF
Esta es sin duda la trampa más frecuente. En SAS© clásico, la condición if eof; solo se dispara una vez, al final de la tabla.
En un entorno distribuido (multihilo), la lógica cambia:
Si ejecuta este código en CAS con varios hilos:
No obtendrá una sola línea, sino tantas líneas como hilos activos haya. Si su sesión utiliza 36 hilos, tendrá 36 observaciones de salida, cada una representando la última línea procesada por ese hilo específico.
Para obtener un total global, a menudo es necesario un paso de agregación adicional (post-procesamiento).
4. Compatibilidad de Funciones
Finalmente, al migrar código, hay que tener en cuenta que no todas las funciones SAS© están implementadas en CAS. Si una función no es compatible de forma nativa con el motor CAS, el sistema a veces puede transferir los datos al servidor de cálculo (Compute Server) para realizar el procesamiento, lo que anula los beneficios de rendimiento del procesamiento distribuido. Se recomienda consultar la documentación para asegurarse de que las funciones utilizadas estén "habilitadas para CAS".
La transición de SAS© 9 a CAS no se limita a cambiar el nombre de la LIBNAME.
Para el rendimiento: CAS sobresale en el procesamiento masivo en memoria y paralelo, pero puede ser menos eficiente en pequeños volúmenes o tareas puramente secuenciales (monohilo).
Para la lógica: Los desarrolladores deben adaptar su "mapa mental". El concepto de lectura secuencial de principio a fin de un solo archivo desaparece en favor de un procesamiento por bloques independientes.