exponenta event banner

Избегать дублирования функций в сгенерированном коде

Проблема

Создается код, содержащий несколько дублированных копий одних и тех же функций с незначительными различиями, например, модификациями подписи функции. Например, созданный код может содержать функции, называемые foo и b_foo. Дублирование функций может затруднить анализ и управление сгенерированным кодом.

Причина

Дублирование функций в сгенерированном коде является результатом специализации функций. Генератор кода специализируется на функциях, когда обнаруживает, что они различаются на разных узлах вызова:

  • Количество входных или выходных переменных.

  • Тип входных или выходных переменных.

  • Размер входных или выходных переменных.

  • Значения входных переменных.

В некоторых случаях эти специализации необходимы для сгенерированного кода C/C + +, поскольку функции C/C + + не имеют такой же гибкости, как функции MATLAB ®. В других случаях генератор кода специализируется на функциях оптимизации генерируемого кода или из-за недостатка информации.

Решение

В некоторых случаях код MATLAB можно изменить во избежание создания дубликатов функций.

Определение повторяющихся функций с помощью отчета о создании кода

Можно определить, создавал ли генератор кода дублирующие функции, проверяя отчет о создании кода или в Simulink ®, отчет MATLAB Function. В отчете представлен список дублирующих функций под функцией точки входа. Например:

Создание дубликатов функций для нескольких входных размеров

Если код MATLAB вызывает функцию несколько раз и передает входы различных размеров, генератор кода может создать специализации функции для каждого размера. Чтобы избежать этой проблемы, используйте coder.ignoreSize на входе функции. Например, этот код использует coder.ignoreSize во избежание создания нескольких копий функции indexOf:

function [out1, out2] = test1(in)
  a = 1:10;
  b = 2:40;
  % Without coder.ignoreSize duplicate functions are generated
  out1 = indexOf(coder.ignoreSize(a), in);
  out2 = indexOf(coder.ignoreSize(b), in);
end

function index = indexOf(array, value)
  coder.inline('never');
  for i = 1:numel(array)
      if array(i) == value
          index = i;
          return
      end
  end
  index = -1;
  return
end

Для создания кода введите:

codegen test1 -config:lib -report -args {1}

Создание дубликатов функций для различных входных значений

Если код MATLAB вызывает функцию и передает несколько различных входов констант, генератор кода может создать специализации функции для каждой отдельной константы. В этом случае используйте coder.ignoreConst указать генератору кода не рассматривать значение как неизменяемую постоянную. Например:

function [out3, out4] = test2(in)
  c = ['a', 'b', 'c'];
  if in > 0
      c(2)='d';
  end
  out3 = indexOf(c, coder.ignoreConst('a')); 
  out4 = indexOf(c, coder.ignoreConst('b')); 
end


function index = indexOf(array, value)
  coder.inline('never');
  for i = 1:numel(array)
      if array(i) == value
          index = i;
          return
      end
  end
  index = -1;
  return
end

Для создания кода введите:

codegen test2 -config:lib -report -args {1}

Создание дубликатов функций для различного количества выходов

Если код MATLAB вызывает функцию и принимает различное количество выходов на различных узлах вызова, генератор кода может создавать специализации для каждого вызова. Например:

[a b] = foo();
c = foo();

Чтобы каждый вызов возвращал одинаковое количество выходов и избежать дублирования функций, используйте ~ символ:

[a b] = foo();
[c, ~] = foo();

См. также

| |

Связанные темы