[Биография] [Диссертация] [Ссылки] [Содержание библиотеки] [Почта] |
Создание 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–директив, выше указанные директивы можно опустить.
Часто в 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 »
Разница очевидна.