Входящий код вызова - многопоточный с постоянными данными (только для Windows)

В этом примере требуются библиотеки, специфичные для Microsoft® Windows® операционная система и, следовательно, работает только на платформах Windows. Это многопоточный пример, в котором используются постоянные данные. Два потока вызывают MATLAB® функциональные matrix_exp с различными наборами входных данных.

Код MATLAB для этого примера

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 <windows.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*/
DWORD WINAPI thread_function(PVOID 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();
    return 0;
}

void main() {
    HANDLE thread1, thread2;
    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");
    thread1 = CreateThread(NULL, 0, thread_function, (PVOID) &data1, 0, NULL);
    if (thread1 == NULL){
		perror( "Thread 1 creation failed.");
		exit(EXIT_FAILURE);
	}

    printf("Starting thread 2...\n");
    thread2 = CreateThread(NULL, 0, thread_function, (PVOID) &data2, 0, NULL);
    if (thread2 == NULL){
        perror( "Thread 2 creation failed.");
        exit(EXIT_FAILURE);
    }
    
    /*Wait for both the threads to finish execution*/
    if (WaitForSingleObject(thread1, INFINITE) != WAIT_OBJECT_0){
		perror( "Thread 1 join failed.");
		exit(EXIT_FAILURE);
	}
    
    if (WaitForSingleObject(thread2, INFINITE) != WAIT_OBJECT_0){
		perror( "Thread 2 join failed.");
		exit(EXIT_FAILURE);
	}  
    
    free(sd1);
    free(sd2);
    free(pd1);
    free(pd2);
    
    printf("Finished Execution!\n");
    exit(EXIT_SUCCESS);
    
}

Сгенерируйте входящий код С

Запустите следующий скрипт в командной строке MATLAB, чтобы сгенерировать код.

% This example can only be run on Windows platforms
if ~ispc
 error...
   ('This example requires Windows-specific libraries and can only be run on Windows.');
end

% Setting the options for the Config object
% Create a code gen configuration object
cfg = coder.config('exe');

% Enable reentrant code generation
cfg.MultiInstanceCode = true;

% Compiling 
codegen -config cfg main.c -report matrix_exp.m -args ones(160,160)

Этот скрипт:

  • Генерирует сообщение об ошибке, если пример не работает на платформе Windows.

  • Создает объект строения генерации кода для генерации исполняемого файла.

  • Включает MultiInstanceCode опция для генерации переиспользуемого, повторно входящего кода.

  • Призывает codegen со следующими опциями:

    • -config для прохождения в объекте строения генерации кода cfg.

    • main.c чтобы включить этот файл в компиляцию.

    • -report для создания отчета генерации кода.

    • -args чтобы задать вход примера с классом, размером и сложностью.

Исследуйте сгенерированный код

codegen генерирует заголовочный файл matrix_exp_types.h, который определяет:

  • The matrix_expStackData глобальная структура, содержащая локальные переменные, которые являются слишком большими для размещения в стеке, и указатель на matrix_expPersistentData глобальная структура.

  • The 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.exe')
Исполняемый файл запускается и сообщает о завершении.

См. также

|