Этот пример требует потока POSIX (pthread) библиотеки и, поэтому, запускается только на платформах UNIX®. Это - многопоточный пример, который использует персистентные данные. Два потока вызывают функцию MATLAB® matrix_exp
с различными наборами входных данных.
function [Y,numTimes] = matrix_exp(X) %#codegen % % The function matrix_exp computes matrix exponential % of the input matrix using Taylor series and returns % the computed output. It also returns the number of % times this function has been called. % persistent count; if isempty(count) count = 0; end count = count+1; E = zeros(size(X)); F = eye(size(X)); k = 1; while norm(E+F-E,1) > 0 E = E + F; F = X*F/k; k = k+1; end Y = E ; numTimes = count; |
Чтобы вызвать повторно используемый код, который использует персистентные данные, обеспечьте main
функция, что:
Включает заголовочный файл matrix_exp.h
.
Для каждого потока, выделяет память для данных о стеке.
Выделяет память для персистентных данных, однажды на корневой процесс, если потоки осуществляют обмен данными, и однажды на поток в противном случае.
Вызывает matrix_exp_initialize
функция обслуживания. Для получения дополнительной информации смотрите, Развертывают Сгенерированный код.
Вызовы matrix_exp
.
Вызовы matrix_exp_terminate
.
Освобождает память, используемую для стека и персистентных данных.
В данном примере main.c
содержит:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include "matrix_exp.h" #include "matrix_exp_initialize.h" #include "matrix_exp_terminate.h" #include "rtwtypes.h" #define NUMELEMENTS (160*160) typedef struct { real_T in[NUMELEMENTS]; real_T out[NUMELEMENTS]; real_T numTimes; matrix_expStackData* spillData; } IODATA; /*The thread_function calls the matrix_exp function written in MATLAB*/ void *thread_function(void *dummyPtr) { IODATA *myIOData = (IODATA*)dummyPtr; matrix_exp_initialize(myIOData->spillData); matrix_exp(myIOData->spillData, myIOData->in, myIOData->out, &myIOData>numTimes); printf("Number of times function matrix_exp is called is %g\n",myIOData->numTimes); matrix_exp_terminate(); } int main() { pthread_t thread1, thread2; int iret1, iret2; IODATA data1; IODATA data2; int32_T i; /*Initializing data for passing to the 2 threads*/ matrix_expPersistentData* pd1 = (matrix_expPersistentData*)calloc(1,sizeof(matrix_expPersistentData)); matrix_expPersistentData* pd2 = (matrix_expPersistentData*)calloc(1,sizeof(matrix_expPersistentData)); matrix_expStackData* sd1 = (matrix_expStackData*)calloc(1,sizeof(matrix_expStackData)); matrix_expStackData* sd2 = (matrix_expStackData*)calloc(1,sizeof(matrix_expStackData)); sd1->pd = pd1; sd2->pd = pd2; data1.spillData = sd1; data2.spillData = sd2; for (i=0;i<NUMELEMENTS;i++) { data1.in[i] = 1; data1.out[i] = 0; data2.in[i] = 1.1; data2.out[i] = 0; } data1.numTimes = 0; data2.numTimes = 0; /*Initializing the 2 threads and passing required data to the thread functions*/ printf("Starting thread 1...\n"); iret1 = pthread_create(&thread1, NULL, thread_function, (void*) &data1); if (iret1 != 0){ perror("Thread 1 creation failed."); exit(EXIT_FAILURE); } printf("Starting thread 2...\n"); iret2 = pthread_create(&thread2, NULL, thread_function, (void*) &data2); if (iret2 != 0){ perror( "Thread 2 creation failed."); exit(EXIT_FAILURE); } /*Wait for both the threads to finish execution*/ iret1 = pthread_join(thread1, NULL); if (iret1 != 0){ perror( "Thread 1 join failed."); exit(EXIT_FAILURE); } iret2 = pthread_join(thread2, NULL); if (iret2 != 0){ perror( "Thread 2 join failed."); exit(EXIT_FAILURE); } free(sd1); free(sd2); free(pd1); free(pd2); printf("Finished Execution!\n"); return(0); } |
Чтобы сгенерировать код, запустите следующий скрипт в командной строке MATLAB.
% This example can only be run on Unix platforms if ~isunix error('This example requires pthread libraries and can only be run on Unix.'); end % Setting the options for the Config object % Specify an ERT target cfg = coder.config('exe'); % Enable reentrant code generation cfg.MultiInstanceCode = true; % Set the post code generation command to be the 'setbuildargs' function cfg.PostCodeGenCommand = 'setbuildargs(buildInfo)'; % Compiling codegen -config cfg main.c -report matrix_exp.m -args ones(160,160) |
Этот скрипт:
Генерирует сообщение об ошибке, если пример не работает на платформе UNIX.
Создает объект настройки генерации кода для генерации исполняемого файла.
Включает MultiInstanceCode
опция, чтобы сгенерировать допускающий повторное использование, повторно используемый код.
Использует PostCodeGenCommand
опция, чтобы установить команду постгенерации кода быть setbuildargs
функция. Эта функция устанавливает -lpthread
отметьте, чтобы указать, что сборка включает pthread библиотеку.
function setbuildargs(buildInfo) % The example being compiled requires pthread support. % The -lpthread flag requests that the pthread library % be included in the build linkFlags = {'-lpthread'}; addLinkFlags(buildInfo, linkFlags);
Для получения дополнительной информации смотрите Индивидуальную настройку Процесса сборки.
Вызывает codegen
со следующими опциями:
-config
передать в объекте cfg
настройки генерации кода.
main.c
включать этот файл в компиляцию.
-report
создать отчет генерации кода.
-args
задавать вход в качестве примера с классом, размером и сложностью.
codegen
генерирует заголовочный файл matrix_exp_types.h
, который задает:
matrix_expStackData
глобальная структура, которая содержит локальные переменные, которые являются слишком большими, чтобы соответствовать на стеке и указателе на matrix_expPersistentData
глобальная структура.
matrix_expPersistentData
глобальная структура, которая содержит персистентные данные.
/* * matrix_exp_types.h * * Code generation for function 'matrix_exp' * */ #ifndef __MATRIX_EXP_TYPES_H__ #define __MATRIX_EXP_TYPES_H__ /* Include files */ #include "rtwtypes.h" /* Type Definitions */ #ifndef typedef_matrix_expPersistentData #define typedef_matrix_expPersistentData typedef struct { double count; } matrix_expPersistentData; #endif /*typedef_matrix_expPersistentData*/ #ifndef typedef_matrix_expStackData #define typedef_matrix_expStackData typedef struct { struct { double F[25600]; double Y[25600]; double X[25600]; } f0; matrix_expPersistentData *pd; } matrix_expStackData; #endif /*typedef_matrix_expStackData*/ #endif /* End of code generation (matrix_exp_types.h) */ |
Вызовите код с помощью команды:
system('./matrix_exp')
Управляйте использованием стекового пространства | Сложите выделение и эффективность