Pregunta Método eficiente para encontrar elementos en la matriz MATLAB


Me gustaría saber cómo se puede tratar el cuello de botella en el fragmento de código dado.

%% Points is an Nx3 matrix having the coordinates of N points where N ~ 10^6
Z = points(:,3)
listZ = (Z >= a & Z < b); % Bottleneck
np = sum(listZ); % For later usage
slice = points(listZ,:);

Actualmente para N ~ 10^6, np ~ 1000 y number of calls to this part of code = 1000, la declaración de cuello de botella está tomando alrededor de 10 segundos en total, que es una gran parte del tiempo en comparación con el resto de mi código.

Profiling Results

Algunas capturas de pantalla más de un código de muestra solo para la declaración de indexación solicitada por @EitanT

Profiling for sample code Profiling for sample code


5
2018-06-20 15:14


origen


Respuestas:


Si la igualdad en un lado no es importante, puede reformularla en una comparación unilateral y obtiene un orden de magnitud más rápido:

Z = rand(1e6,3);
a=0.5; b=0.6;
c=(a+b)/2;
d=abs(a-b)/2;
tic
for k=1:100,
    listZ1 = (Z >= a & Z < b); % Bottleneck
end
toc

tic
for k=1:100,
    listZ2 = (abs(Z-c)<d);
end
toc

isequal(listZ1, listZ2)

devoluciones

Elapsed time is 5.567460 seconds.
Elapsed time is 0.625646 seconds.

ans =

     1

8
2018-06-20 16:25



Suponiendo el peor de los casos:

  • elemento sabio & no está cortocircuitado internamente
  • las comparaciones son de un solo hilo

Estás haciendo 2*1e6*1e3 = 2e9 comparaciones en ~ 10 segundos. Eso es ~ 200 millones de comparaciones por segundo (~ 200 MFLOPS).

Teniendo en cuenta que puedes hacer algo 1.7 GFLops en un solo núcleo, esto de hecho parece bastante bajo.

¿Estás ejecutando Windows 7? Si es así, ¿has comprobado tu configuración de energía? Se encuentra en un procesador móvil, por lo que espero que, de manera predeterminada, haya algún esquema de bajo consumo de energía en vigor. Esto permite que las ventanas reduzcan la velocidad de procesamiento, así que ... compruebe eso.

Aparte de eso ... Realmente no tengo ni idea.


3
2018-06-20 16:11



Intenta hacer algo como esto:

for i = 1:1000
    x = (a >= 0.5);
    x = (x < 0.6);
end

Me pareció más rápido que:

for i = 1:1000
    x = (a >= 0.5 & a < 0.6);
end

por unos 4 segundos:

Elapsed time is 0.985001 seconds. (first one)
Elapsed time is 4.888243 seconds. (second one)

Creo que la razón de su desaceleración es el elemento sabio & operación.


1
2018-06-20 15:58



Preguntas populares