Эффективный метод поиска элементов в матрице MATLAB

Я хотел бы знать, как можно устранить узкое место в данном фрагменте кода.

%% 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,:);

В настоящее время для N ~ 10^6, np ~ 1000 а также number of calls to this part of code = 1000утверждение узкого места занимает в общей сложности около 10 секунд, что является большим отрезком времени по сравнению с остальной частью моего кода.

Результаты профилирования

Еще несколько скриншотов примера кода только для оператора индексации по запросу @EitanT

Профилирование для примера кодаПрофилирование для примера кода

3 ответа

Решение

Если равенство с одной стороны не имеет значения, вы можете переформулировать его для одностороннего сравнения, и оно будет на один порядок быстрее:

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)

возвращается

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

ans =

     1

Предполагая наихудший случай:

  • поэлементно & не закорочен внутри
  • сравнения однопоточные

Ты делаешь 2*1e6*1e3 = 2e9 сравнения за ~10 секунд. Это ~200 миллионов сравнений в секунду (~200 MFLOPS).

Учитывая, что вы можете сделать 1.7 GFLops на одном ядре, это действительно кажется довольно низким.

Вы используете Windows 7? Если да, проверили ли вы свои настройки питания? Вы работаете на мобильном процессоре, поэтому я ожидаю, что по умолчанию будет действовать схема с низким энергопотреблением. Это позволяет Windows уменьшить скорость обработки, так что... проверьте это.

Кроме этого.... Я действительно понятия не имею.

Попробуйте сделать что-то вроде этого:

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

Я нашел это быстрее, чем:

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

примерно на 4 секунды:

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

Я думаю, что причиной вашего замедления является элемент мудрый & операция.

Другие вопросы по тегам