performance matlab benchmarking vectorization bsxfun

performance - Comparando BSXFUN y REPMAT



matlab benchmarking (1)

Se hicieron pocas preguntas antes sobre las comparaciones entre bsxfun y repmat para el rendimiento.

  • Uno de ellos fue: Matlab - bsxfun no longer faster than repmat? . Este trató de investigar las comparaciones de rendimiento entre repmat y bsxfun , específicas para realizar la resta de la media de una matriz de entrada a lo largo de las columnas de la matriz de entrada y, como tal, exploraría solo la parte bsxfun de bsxfun contra su equivalente repmat .
  • Otro fue: In Matlab, when is it optimal to use bsxfun? . Ese intentó hacer la misma operación de sustracción por la media a lo largo de las columnas y tampoco se expandió a otras operaciones integradas.

Con esta publicación, estoy tratando de investigar los números de rendimiento entre bsxfun y repmat para cubrir todos los bsxfun integrados de bsxfun para darle una perspectiva más amplia, ya que estas dos buenas soluciones vectorizadas presentan.

Específicamente, mis preguntas con esta publicación son:

  1. ¿Cómo funcionan las diversas operaciones bsxfun con bsxfun frente a equivalentes repmat ? bsxfun admite operaciones de punto flotante como @plus , @minus , @times , etc. y también operaciones relacionales y lógicas como @ge , @and , etc. Entonces, ¿hay incorporaciones específicas que me darían aceleraciones notables con bsxfun que usar sus equivalentes repmat ?

  2. Loren en su blog post ha comparado repmat contra bsxfun con sincronización @() A - repmat(mean(A),size(A,1),1) contra @() bsxfun(@minus,A,mean(A)) respectivamente . Si necesito cubrir el benchmarking para todos los elementos integrados, ¿puedo usar algún otro modelo de comparación que funcione con operaciones de punto flotante, relacionales y lógicas?


Introducción

El debate sobre si bsxfun es mejor que repmat o viceversa ha estado sucediendo desde siempre. En esta publicación, intentaremos comparar cómo las diferentes incorporaciones que se envían con MATLAB luchan contra los equivalentes repmat en términos de sus actuaciones en tiempo de ejecución y esperamos sacar algunas conclusiones significativas de ellas.

Conociendo las funciones integradas de BSXFUN

Si la documentación oficial se extrae del entorno de MATLAB o del sitio web de Mathworks , se puede ver la lista completa de funciones integradas compatibles con bsxfun . Esa lista tiene funciones para punto flotante, operaciones relacionales y lógicas.

En MATLAB 2015A , las operaciones de punto flotante compatibles con elementos son:

  • @plus (sumatoria)
  • @minus (resta)
  • @times (multiplicación)
  • @rdivide (división a la derecha)
  • @ldivide (división a la izquierda)
  • @pow (poder)
  • @rem (resto)
  • @mod (módulo)
  • @ atan2 (tangente inversa de cuatro cuadrantes)
  • @ atan2d (tangente inversa de cuatro cuadrantes en grados)
  • @hypot (raíz cuadrada de la suma de cuadrados).

El segundo conjunto consiste en operaciones relacionales basadas en elementos y esas son:

  • @eq (igual)
  • @ne (no igual)
  • @lt (menor que)
  • @le (menor o igual que)
  • @gt (mayor que)
  • @ge (mayor que o igual).

El tercer y último conjunto se compone de operaciones lógicas que se enumeran aquí:

  • @and (lógico y)
  • @or (lógico o)
  • @xor (xor lógico).

Tenga en cuenta que hemos excluido dos incorporados @max (maximum) y @min (minimum) de nuestras pruebas de comparación, ya que podría haber muchas formas en que uno puede implementar sus equivalentes repmat .

Modelo de comparación

Para comparar realmente el rendimiento entre repmat y bsxfun , debemos asegurarnos de que los tiempos solo necesiten cubrir las operaciones previstas. Por lo tanto, algo como bsxfun(@minus,A,mean(A)) no será ideal, ya que tiene que calcular la mean(A) dentro de esa llamada bsxfun , por insignificante que sea el tiempo. En cambio, podemos usar otra entrada B del mismo tamaño que la mean(A) .

Por lo tanto, podemos usar: A = rand(m,n) & B = rand(1,n) , donde n son los parámetros de tamaño que podríamos variar y estudiar los rendimientos basados ​​en ellos. Esto se hace exactamente en nuestras pruebas de evaluación comparativa que se enumeran en la siguiente sección.

Las versiones repmat y bsxfun para operar en esas entradas se verían así:

REPMAT: A + repmat(B,size(A,1),1) BSXFUN: bsxfun(@plus,A,B)

Benchmarking

Finalmente, estamos en el meollo de esta publicación para ver a estos dos tipos pelear. Hemos segregado la evaluación comparativa en tres conjuntos, uno para las operaciones de coma flotante, otro para las operaciones relacionales y el tercero para las operaciones lógicas. Hemos extendido el modelo de comparación como se discutió anteriormente a todas estas operaciones.

Set1: operaciones de punto flotante

Aquí está el primer conjunto de código de evaluación comparativa para operaciones de punto flotante con repmat y bsxfun :

datasizes = [ 100 100; 100 1000; 100 10000; 100 100000; 1000 100; 1000 1000; 1000 10000; 10000 100; 10000 1000; 10000 10000; 100000 100; 100000 1000]; num_funcs = 11; tsec_rep = NaN(size(datasizes,1),num_funcs); tsec_bsx = NaN(size(datasizes,1),num_funcs); for iter = 1:size(datasizes,1) m = datasizes(iter,1); n = datasizes(iter,2); A = rand(m,n); B = rand(1,n); fcns_rep= {@() A + repmat(B,size(A,1),1),@() A - repmat(B,size(A,1),1),... @() A .* repmat(B,size(A,1),1), @() A ./ repmat(B,size(A,1),1),... @() A./repmat(B,size(A,1),1), @() A .^ repmat(B,size(A,1),1),... @() rem(A ,repmat(B,size(A,1),1)), @() mod(A,repmat(B,size(A,1),1)),... @() atan2(A,repmat(B,size(A,1),1)),@() atan2d(A,repmat(B,size(A,1),1)),... @() hypot( A , repmat(B,size(A,1),1) )}; fcns_bsx = {@() bsxfun(@plus,A,B), @() bsxfun(@minus,A,B), ... @() bsxfun(@times,A,B),@() bsxfun(@rdivide,A,B),... @() bsxfun(@ldivide,A,B), @() bsxfun(@power,A,B), ... @() bsxfun(@rem,A,B), @() bsxfun(@mod,A,B), @() bsxfun(@atan2,A,B),... @() bsxfun(@atan2d,A,B), @() bsxfun(@hypot,A,B)}; for k1 = 1:numel(fcns_bsx) tsec_rep(iter,k1) = timeit(fcns_rep{k1}); tsec_bsx(iter,k1) = timeit(fcns_bsx{k1}); end end speedups = tsec_rep./tsec_bsx;

Set2: operaciones relacionales

El código de evaluación comparativa para fcns_rep operaciones relacionales reemplazaría fcns_rep y fcns_bsx del código de evaluación comparativa anterior con estas contrapartes:

fcns_rep = { @() A == repmat(B,size(A,1),1), @() A ~= repmat(B,size(A,1),1),... @() A < repmat(B,size(A,1),1), @() A <= repmat(B,size(A,1),1), ... @() A > repmat(B,size(A,1),1), @() A >= repmat(B,size(A,1),1)}; fcns_bsx = { @() bsxfun(@eq,A,B), @() bsxfun(@ne,A,B), @() bsxfun(@lt,A,B),... @() bsxfun(@le,A,B), @() bsxfun(@gt,A,B), @() bsxfun(@ge,A,B)};

Set3: operaciones lógicas

El conjunto final de códigos de evaluación comparativa utilizaría las operaciones lógicas que se enumeran aquí:

fcns_rep = { @() A & repmat(B,size(A,1),1), @() A | repmat(B,size(A,1),1), ... @() xor(A,repmat(B,size(A,1),1))}; fcns_bsx = { @() bsxfun(@and,A,B), @() bsxfun(@or,A,B), @() bsxfun(@xor,A,B)};

Tenga en cuenta que para este conjunto específico, los datos de entrada, A y B necesarios eran matrices lógicas. Entonces, tuvimos que hacer estas ediciones en el código de evaluación comparativa anterior para crear matrices lógicas:

A = rand(m,n)>0.5; B = rand(1,n)>0.5;

Tiempos de ejecución y observaciones

Los códigos de evaluación comparativa se ejecutaron en esta configuración del sistema:

MATLAB Version: 8.5.0.197613 (R2015a) Operating System: Windows 7 Professional 64-bit RAM: 16GB CPU Model: Intel® Core i7-4790K @4.00GHz

Las aceleraciones así obtenidas con bsxfun sobre repmat después de ejecutar las pruebas de referencia se trazaron para los tres conjuntos como se muestra a continuación.

A. Operaciones de punto flotante:

Pocas observaciones podrían extraerse del diagrama de aceleración:

  • Los dos casos de aceleración notablemente mejores con bsxfun son para atan2 y atan2d .
  • A continuación en esa lista están las operaciones de división derecha e izquierda que aumenta el rendimiento con 30% - 50% sobre los códigos equivalentes repmat .
  • Más abajo en esa lista están las 7 operaciones restantes cuyas aceleraciones parecen muy cercanas a la unidad y, por lo tanto, necesitan una inspección más cercana. El diagrama de aceleración podría reducirse a solo esas 7 operaciones como se muestra a continuación:

Según el gráfico anterior, se podría ver que, salvo los casos @hypot con @hypot y @mod , bsxfun aún funciona aproximadamente un 10% mejor que repmat para estas 7 operaciones.

B. Operaciones relacionales:

Este es el segundo conjunto de benchmarking para las siguientes 6 operaciones relacionales bsxfun soportadas por bsxfun .

Mirando el diagrama de aceleración anterior, descuidando el caso inicial que tenía tiempos de ejecución comparables entre bsxfun y repmat , uno puede ver fácilmente que bsxfun gana para estas operaciones relacionales. Con aceleraciones que tocan 10x , bsxfun siempre sería preferible para estos casos.

C. Operaciones lógicas:

Este es el tercer conjunto de benchmarking para las 3 operaciones lógicas integradas restantes soportadas por bsxfun .

Al @xor caso de tiempo de ejecución comparable @xor para @xor al principio, bsxfun parece tener una ventaja para este conjunto de operaciones lógicas también.

Conclusiones

  1. Cuando se trabaja con operaciones relacionales y lógicas, repmat podría repmat fácilmente en favor de bsxfun . Para el resto de los casos, aún se puede persistir con bsxfun si se bsxfun uno de los casos con un rendimiento de 5 - 7% menor.
  2. Al ver el tipo de gran aumento del rendimiento cuando se usan operaciones relacionales y lógicas con bsxfun , uno puede pensar en usar bsxfun para trabajar en datos con ragged patterns , algo así como matrices de celdas para beneficios de rendimiento. Me gusta llamar a estos casos de solución como los que usan la capacidad de enmascaramiento de bsxfun . Esto básicamente significa que creamos matrices lógicas, es decir, máscaras con bsxfun , que pueden usarse para intercambiar datos entre matrices de celdas y matrices numéricas. Una de las ventajas de tener datos viables en matrices numéricas es que los métodos vectorizados podrían usarse para procesarlos. Nuevamente, dado que bsxfun es una buena herramienta para la vectorización, es posible que lo esté utilizando una vez más trabajando en el mismo problema, por lo que hay más razones para conocer bsxfun . Pocos casos de solución donde pude explorar tales métodos están vinculados aquí para beneficio de los lectores: 1 , 2 , 3 , 4 , 5 .

Trabajo futuro

El presente trabajo se centró en replicar datos a lo largo de una dimensión con repmat . Ahora, repmat puede replicarse a lo largo de múltiples dimensiones y también bsxfun con sus expansiones equivalentes a las replicaciones. Como tal, sería interesante realizar pruebas similares en replicaciones y expansiones en múltiples dimensiones con estas dos funciones.