Проверьте, если только один раз - PullRequest
1 голос
/ 08 июля 2019

В функции MATLAB используется следующий код:

function stuff()

  if a == 2

    do1();

  else

    do2();

  end
end

Этот код помещается в цикл имитации и вызывается 1000 или более раз в секунду.if -статист имеет значение только при первом вызове функции, после чего либо do1, либо do2, переменная a больше не изменится.

Как мне предотвратить потерю времени на обработку с этим if заявлением?По сути, как мне сказать Matlab, чтобы больше не проверять оператор if, а просто вызвать одну функцию, которая выбирается при первом вызове stuff?

Ответы [ 3 ]

5 голосов
/ 08 июля 2019

Вопреки вашим убеждениям, это не проблема, компилятор (должен) автоматически выполнит эту оптимизацию за вас.См., Например, Цикл-инвариантный код движения .

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

flag = a==2;
for i = 1:100
    stuff(flag)
end

Тогда вам нужно будет выполнить вычисление только один раз, и это яснокомпилятору, что значение не меняется.

ПРИМЕЧАНИЕ. Очевидно, что если ваша проверка действительно a==2, это не будет иметь большого значения.

РЕДАКТИРОВАТЬ: Я не смог точно убедиться, что MATLAB делает это автоматически.Тем не менее, это только первый уровень оптимизации, который сделан для вас.Все современные процессоры используют так называемый предсказатель ветвления, см., Например, этот блестящий ответ Почему обработка отсортированного массива быстрее, чем обработка несортированного массива? , или эта вики-страница .Короче говоря, процессор угадывает результат оператора if, если он правильный, все идет быстрее.Я думаю, будет справедливо сказать, что процессор угадывает правильно во всех ваших случаях.

TLDR: Не беспокойтесь об этом.

3 голосов
/ 08 июля 2019

Учитывая комментарии выше, кажется, что вы на самом деле ищете способ динамического выбора функции, которая будет запущена в вашей симуляции.Этот выбор должен быть динамическим (вы не знаете, какую функцию использовать во время выполнения), но выбор должен быть сделан только один раз.Этого легко достичь, используя функциональные дескрипторы: https://www.mathworks.com/help/matlab/function-handles.html

Вот пример:

    function dynamicSimulation()
        if ( rand() > 0.5 ) % determine which function should be called dynamically
            sim=@func1;
        else
            sim=@func2;
        end
        other_params = [];

        for k = 1:5 % run the simulation
            sim( k, other_params );
        end
    end

    function func1( index, other_params )
        fprintf( 'Index=%d: Simulating using function 1\n', index );
    end

    function func2( index, other_params )
        fprintf( 'Index=%d: Simulating using function 2\n', index );
    end

Если вы выполните это несколько раз, вы заметите, что (случайный) выбор func1 или func2будет означать, что вы не запускаете одну и ту же функцию каждый раз, хотя одна и та же функция используется для всей симуляции.

1 голос
/ 08 июля 2019

Я считаю, что вы не тратите много времени на проверку правильности этого утверждения if.Однако, поскольку вы специально упомянули, он проверяет только первую итерацию: почему бы не получить это?Таким образом, вместо:

for ii = 1:10
    if ii == 1
        k = 1;
    else
        k = k + 1;
    end
end

Вы можете сделать

k = 1;
for ii = 2:10
    k = k + 1;
end

Таким образом, исключив проверку.

Примечание: это плохо масштабируется, конечно, но какздесь только одна итерация, я считаю ее хорошим вариантом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...