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 entrerepmat
ybsxfun
, 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 partebsxfun
debsxfun
contra su equivalenterepmat
. -
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:
-
¿Cómo funcionan las diversas operaciones
bsxfun
conbsxfun
frente a equivalentesrepmat
?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 conbsxfun
que usar sus equivalentesrepmat
? -
Loren en su
blog post
ha comparadorepmat
contrabsxfun
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 paraatan2
yatan2d
. -
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 equivalentesrepmat
. -
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 esas7
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
-
Cuando se trabaja con operaciones relacionales y lógicas,
repmat
podríarepmat
fácilmente en favor debsxfun
. Para el resto de los casos, aún se puede persistir conbsxfun
si sebsxfun
uno de los casos con un rendimiento de5 - 7%
menor. -
Al ver el tipo de gran aumento del rendimiento cuando se usan operaciones relacionales y lógicas con
bsxfun
, uno puede pensar en usarbsxfun
para trabajar en datos conragged 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 debsxfun
. Esto básicamente significa que creamos matrices lógicas, es decir, máscaras conbsxfun
, 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 quebsxfun
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 conocerbsxfun
. 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.