Parallel Assign() es lento en ciertos dispositivosHola a todos,
Parece haber un problema con Parallel Assign() en combinación con ciertos sistemas.
Tengo acceso a 3 PC con Windows 10 con JMP 16.1:
- Computadora portátil: Core i5-8350U (4 núcleos) a 1,9 GHz, 16 GB de RAM
- Estación de trabajo antigua: Xeon E5-1660 v4 (8 núcleos) a 3,2 GHz, 256 GB de RAM
- Nueva estación de trabajo Xeon W-2145 (8 núcleos) a 3,7 GHz, 128 GB de Ram
Comparé el rendimiento de la versión paralela y secuencial de mi script de prueba utilizando diferentes tamaños de problemas en todos los sistemas (cifrado a continuación).
El resultado fue sorprendentemente malo. Sólo en mi portátil la versión paralela es ligeramente más rápida que la versión secuencial, pero hasta más de 2 veces más lenta en las estaciones de trabajo.
¿Alguien experimentó problemas de rendimiento similares con Parallel Assign()? ¿O lo estoy usando mal? ¿Que esta pasando aqui?
Robar


n_different_ids = 100000;
<BR />// Just generate random data. Every 15 rows must be processed at the same time.
DT_Data = J( 15*n_different_ids, 9, 0 );
For ( i = 1, i <= n_different_ids, i++,
DT_Data[15*(i-1)+(1::15),0] = i + J( 15, 9, Random Normal() );
);
<BR />// some function
F_percentile = Function( {x , p},
x = Sort Ascending(x);
n = N Rows(x);
index = 1 + (n - 1) * p;
index_ibelow = Floor(index);
index_iabove = Ceiling(index);
h = index - index_ibelow;
result = (1 - h) * x[index_ibelow] + h * x[index_iabove];
result;
);
<BR />// parallel version
DT_Features = J( n_different_ids, 16, 0 );
start=tick seconds();
Parallel Assign( {
DT_Data = DT_Data,
F_percentile = Name Expr( F_percentile )
},
DT_Features[i,j] = (
i_same_group = Loc(DT_Data[15*(i-1)+(1::15), 1]);
data = DT_Data[15*(i-1)+i_same_group, 1+Ceiling(j/2)];
If (mod(j,2),
result = F_percentile(data, 0.95);
,
result = F_percentile(data, 0.05);
);
result;
)
);
time_parallel = tick seconds()-start;
Show(time_parallel);
Wait(0.1);
<BR />// sequential version
DT_Features = J( n_different_ids, 16, 0 );
start=tick seconds();
for(i=1,i<=n_different_ids,i++,
for(j=1,j<=16,j++,
i_same_group = Loc(DT_Data[15*(i-1)+(1::15), 1]);
data = DT_Data[15*(i-1)+i_same_group, 1+Ceiling(j/2)];
If (mod(j,2),
result = F_percentile(data, 0.95);
,
result = F_percentile(data, 0.05);
);
DT_Features[i,j] =result;
);
);
time_sequential = tick seconds()-start;
Show(time_sequential);
Modelado estadístico avanzadoAutomatización y secuencias de comandosAcceso a los datosExploración y visualización de datosLa personalización en masaIngeniería de Calidad y ProcesosCompartir y comunicar resultadosRe: Parallel Assign() es lento en ciertos dispositivosHola @ih ,
aceptar.
Los gastos generales de preparar a un niño no importan mucho en mi caso, así que no dediqué mucho tiempo a hacer esto lo más efectivo posible. Este script no está pensado para ejecutarse sólo unos minutos. Antes de comenzar con este tema, hice exactamente lo que sugeriste. Dividí mi conjunto de datos en 8 partes y lo terminé en 0,5 días. Por interés, también probé la versión "Sequential_Expr_Opt" de Evan más tarde, y me tomó entre 1,5 y 4 días terminar mi conjunto de datos (lo comencé el jueves por la mañana, no se terminó el viernes por la tarde sino el lunes por la mañana).
Este hilo fue para mostrar que algo anda mal detrás de escena en general. En el pasado noté un mal rendimiento paralelo de JMP de vez en cuando y eso me molestó. Me gusta JMP y me gusta probar cosas que otras personas dicen que no se pueden hacer con JMP. Y estoy más que feliz de que los desarrolladores lo estén investigando.
Sin embargo, debo decir que existen mejores herramientas que JMP para manejar conjuntos de datos realmente grandes. Al menos por el momento. 
Re: Parallel Assign() es lento en ciertos dispositivosHola @Robb , dos pensamientos:
Programación para la velocidad
El objetivo de tu código puede tener un gran efecto en cómo lo escribes.Para la gran mayoría de los scripts, el tiempo adicional que lleva llamar a una función o copiar un símbolo no importa, por lo que sí debes usar funciones y hacer que el código sea fácil de interpretar.Por otro lado, si está trabajando en un proyecto que será grande y se repetirá tantas veces como para que le importe cuánto tiempo lleva, entonces sí, es posible que desee comenzar a cambiar algunas sutilezas por un rendimiento bruto.Sin embargo, te animo a que sólo dediques tiempo a optimizar las cosas que realmente importan.No gastes una hora extra codificando algo ahora y luego tengas que pasar una hora extra averiguando qué hiciste después de un año porque lo hiciste más complejo tratando de acelerarlo, solo para ahorrarles a los usuarios 20 segundos adicionales una vez al día. .
Compensación paralela
Al decidir si ejecutar en paralelo, debe equilibrar la sobrecarga de configurar ese subproceso "secundario" con el trabajo que va a realizar.Imagine que va a ejecutar trabajos paralelos abriendo otra copia de JMP, abriendo una tabla de datos y haciendo clic en ejecutar. Si lo deja ejecutándose durante una hora, entonces genial, ahorrará mucho tiempo al dejar que un script haga todo, pero si ese script se va a ejecutar durante 20 segundos, entonces probablemente haya dedicado más tiempo a iniciarlo que a guardarlo.Sí, la sobrecarga aquí es mucho menor, pero copiar símbolos y asignar memoria lleva tiempo.Asegúrese de que el trabajo que realizará su script una vez configurado el entorno sea sustancial.Una forma de ayudar a que esto suceda es dividir el bucle en solo 4 partes y hacer que cada hilo trabaje en una cuarta parte de los valores a la vez.Por lo tanto, divida su lista en cuatro partes, cada una con una cuarta parte de las filas, y luego haga que su script procese secuencialmente cada sublista. De esa manera, reduce el tiempo dedicado a configurar subprocesos secundarios de n filas() veces a 4.
Re: Parallel Assign() es lento en ciertos dispositivosSeguí el consejo de Craiges y me comuniqué con el soporte técnico hace dos semanas. Después de algunas consultas sobre mis PC, hoy recibí la respuesta de que los desarrolladores han participado para investigar el comportamiento y solucionar problemas en una futura versión de JMP.
Sin embargo, gracias nuevamente Evan por acelerar este script específico.
Re: Parallel Assign() es lento en ciertos dispositivos¡Oh, guau, gracias! Al ejecutar su script en mi estación de trabajo más nueva, obtengo
Paralelo: 37.0833333333139
Secuencial: 19.7166666666453
Expr_paralelo: 6.93333333331975
Expr_secuencial: 12.5333333333256
Sequential_Expr_Opt: 4.54999999998836
No consideremos el Sequential_Expr_Opt porque es una comparación injusta. 
¿Acabas de reemplazar la función por una expresión y obtengo una aceleración de aproximadamente 1,5 para la versión secuencial y más de 5 (!!!) para la versión paralela? Esa es una gran solución. Entonces, ¿qué aprendo de esto? ¿Nunca usas funciones en JSL? Esto es un poco desagradable porque las funciones hacen que el código sea más legible y más fácil y seguro de usar y modificar para otros. Sin embargo, creo que todavía hay un problema detrás de escena porque mi versión paralela original todavía toma el doble de tiempo que la secuencial original y este no es el caso en la máquina virtual de Craige.
Actualización: aquí está el análisis completo de la nueva estación de trabajo:


Re: Parallel Assign() es lento en ciertos dispositivosPara mi máquina de 4 núcleos a 3,6 GHz y N=100k:
Obtengo una aceleración de 1,4 veces utilizando el código paralelo en lugar del secuencial (12,8 segundos en paralelo frente a 17,8 segundos en secuencial). Esto no es tan bueno como la aceleración de 2.7X que Craige estaba viendo, pero es mejor que el comportamiento de desaceleración que estaba viendo en las estaciones de trabajo. Sin embargo, quería ver si podía sacarle un poco más de rendimiento a esto, así que hice algunas modificaciones.
Eliminé la sobrecarga de llamadas a funciones (copias de argumentos de matriz, etc.) usando expresiones en su lugar. Esto me llevó a una aceleración de 2,5 veces (4,5 segundos en paralelo frente a 11,3 segundos en secuencial) y un poco más rápido que el original. Y finalmente, intenté reorganizar un poco los bucles y reduje la versión secuencial a 4 segundos. Esto es más rápido que la versión paralela, pero la reorganización no es tan fácil de hacer con Parallel Assign. Probé algunos N diferentes y estos patrones parecieron mantenerse, pero no hice un barrido completo como en la tabla anterior. Encuentra el código adjunto.
Paralelo: 12,78
Secuencial: 17.80
Expr_paralelo: 4,50
Expr_secuencial: 11.27
Opción_expr_secuencial: 3,98
Re: Parallel Assign() es lento en ciertos dispositivosTambién limité la cantidad de núcleos en el administrador de tareas que están disponibles para JMP a 2, 4 y 8 en la nueva estación de trabajo. La versión paralela sigue siendo más lenta que la secuencial. Supongo que JMP está utilizando bibliotecas obsoletas en segundo plano que no funcionan correctamente en nuevas arquitecturas de hardware.
Gracias Craige, me pondré en contacto con el soporte técnico al respecto.
Re: Parallel Assign() es lento en ciertos dispositivosNo estoy seguro. Envié una nota sobre este hilo a JMP; Es posible que también quieras hablar con el soporte técnico.
Mi conjetura (¡y eso es todo!) es que JMP necesitará cambiar algo para recuperar el rendimiento del nuevo hardware. Con sólo 4 CPU virtuales, no puedo ver lo mismo que tú.
Re: Parallel Assign() es lento en ciertos dispositivosPuedo confirmar ese comportamiento en mi computadora portátil (Win 10, JMP 16.1):
tiempo_paralelo = 158,7;
tiempo_secuencial = 157,766666666667;
norte=1000000
Re: Parallel Assign() es lento en ciertos dispositivosHola Craige,
Ahora estoy mirando mi estación de trabajo con peor rendimiento (abajo). No vi nada sospechoso en el Administrador de tareas. Excepto la CPU, nada está cerca de la ocupación total.
Lo que también noté es que JMP 15.2.1 es siempre más rápido en las versiones paralela y secuencial. En el caso de n=100.000, JMP 16.1 toma alrededor de 36 s/18 s (paralelo/secuencial) y JMP 15.2.1 31 s/15 s, que es un poco mejor pero aún está lejos de un buen rendimiento en paralelo. Desafortunadamente, ya no tengo una versión anterior disponible. Escribí este código usando JMP 12 y no noté problemas de rendimiento en ese entonces (y las PC que estaba usando también eran diferentes).
Robar

Re: Parallel Assign() es lento en ciertos dispositivosEsta es una máquina JMP16/win10 de 4 CPU, 16 GB ~ 3 GHz en VirtualBox. Veo la velocidad que esperaría (no 4X, pero sigue siendo buena).
n_diferentes_id = 100.000;
tiempo_paralelo = 13.9833333333333;
tiempo_secuencial = 37,7333333333333;
n_diferentes_id = 1.000.000;
tiempo_paralelo = 141.233333333333;
tiempo_secuencial = 375.016666666667;
La asignación paralela consiste en copiar una matriz grande para cada CPU, pero los gráficos lineales no sugieren que sea un problema de paginación, en estos tamaños.
Mire el monitor de tareas de Windows para conocer el uso de CPU y memoria (y disco) y vea si explica algo. Vi el 100 % durante la asignación paralela y el 25 % durante la prueba secuencial. También vi que se utilizaron 7 GB durante la asignación paralela más grande.
task managertask managertask managertask manageradministrador de tareas
Re: La función Parallel Assign() es lenta en ciertos dispositivos.Hola a todos,
¡Excelentes noticias! Después de 3 años, volví a ejecutar las 5 pruebas de rendimiento en paralelo (gracias de nuevo a @EvanMcCorkle ) en uno de los ordenadores que ya tenía entonces, esta vez con JMP 19.0.4. El rendimiento en paralelo mejoró mucho en comparación con JMP 16 al usar expresiones. JMP 19 es aproximadamente 5 veces más rápido, lo que es similar a la prueba "Sequential_Expr_Opt" con ambas versiones de JMP. Aun así, se deben evitar las funciones al usar Parallel Assign(), aunque el rendimiento haya mejorado ligeramente.
Salud
Robar
