[Биография]      [Диссертация]     [Ссылки]     [Содержание библиотеки]     [Почта]

Создание MEX-файлов на основе m-функций

Источник:
users.kaluga.ru/webpublic/matlab/theme4_1.htm

Для создания MEX–файла из m–файла, последний должен быть представлен как m–функция, например:

function g = squibo(n)
g = zeros(1,n);
g(1)=1;
g(2)=1;
for i=3:n
   g(i) = sqrt(g(i-1)) + g(i-2);
end

Сохраните функцию и введите такую команду:

» tic; for i = 1:10; squibo(10000); end; toc

elapsed_time =

      4.7600
»

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

» mcc squibo
» tic; for i = 1:10; squibo(10000); end; toc

elapsed_time =

      3.0500

»

То есть мы получили прирост скорости, однако он невелик, всего около 35%. Для повышения скорости необходимо использовать директивы: -r (все числа действительные), -i (размеры матрицы фиксированы):

» mcc –ri squibo
» tic; for i = 1:10; squibo(10000); end; toc

elapsed_time =

      0.0510

»

Теперь скорость вычислений заметно возросла. Директивы влияют на код входного языка компилятора. Это и обуславливает разную скорость. Директивы –r и –i можно заменить указанием в m–файле pragma–директив. Указание в m–файле директивы %#inbounds эквивалентно директиве –i компилятора, а директивы %#realonly эквивалентно –r. При указании pragma–директив, выше указанные директивы можно опустить.

Компиляция двух функций в один MEX-файл

Часто в m–файле (1) осуществляется вызов другой m-функции (2). При компиляции (1), функция (2) может быть тоже откомпилирована (заменена аналогичной API–функцией), а может быть осуществлено обращение из MEX–файла к интерпретатору для вычисления этой функции (2). Обращение к интерпретатору (даже если функция (2) является MEX–файлом) нежелательно из–за потери скорости, особенно в цикле. Необходимо, чтобы функции (1) и (2) были скомпилированы в единый MEX–файл. Чтобы определить, для каких функций будет осуществляться вызов интерпретатора из MEX–файла, при компиляции указывается директива –w. Например:

function g = squibo(n)
%#realonly 
%#inbounds
g = zeros(1,n);
g(1)=1;
g(2)=1;
for i=3:n
   g(i) = sqrt(g(i-1)) + g(i-2) + myfunc(i);
end

function z = myfunc(x)
%#realonly 
%#inbounds
temp1 = x * 10 * sin(x);
z = round(temp1);


» mcc squibo
» tic; squibo(10000); toc

elapsed_time =

   2.3700

» mcc –w squibo

Warning: MATLAB callback of 'myfunc' will be slow (line 8)

Для предотвращения вызовов, обе функции должны быть скомпилированы в один MEX–файл таким образом:

» mcc -w squibo myfunc
» tic; squibo(10000); toc

elapsed_time =

   0.0490

»

Разница очевидна.