Skip to content

Commit

Permalink
Add a new memory pool for hpcom using a lock and no GC (string alloca…
Browse files Browse the repository at this point in the history
…tions are malloc'ed and never free'd)

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@17812 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Oct 22, 2013
1 parent c4fc2ac commit 971d825
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 38 deletions.
16 changes: 3 additions & 13 deletions Compiler/BackEnd/BackendVariable.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2143,20 +2143,10 @@ protected function vararrayList2
input list<BackendDAE.Var> inVarLst;
output list<BackendDAE.Var> outVarLst;
algorithm
outVarLst:=
matchcontinue (arr,pos,inVarLst)
local
BackendDAE.Var v;
outVarLst := match (arr,pos,inVarLst)
case (_,0,_) then inVarLst;
case (_,_,_)
equation
SOME(v) = arr[pos];
then
vararrayList2(arr,pos-1,v::inVarLst);
case (_,_,_)
then
vararrayList2(arr,pos-1,inVarLst);
end matchcontinue;
else then vararrayList2(arr,pos-1,List.consOption(arr[pos],inVarLst));
end match;
end vararrayList2;

public function copyVariables
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Template/CodegenC.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ template simulationFile(SimCode simCode, String guid)
int res;
DATA data;
setupDataStruc(&data);
GC_init();
<%if Flags.isSet(HPCOM) then 'omc_alloc_interface = omc_alloc_interface_pooled;<%\n%>'%>omc_alloc_interface.init();
res = _main_SimulationRuntime(argc, argv, &data);
return res;
}
Expand Down
12 changes: 12 additions & 0 deletions SimulationRuntime/c/openmodelica.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,16 @@ typedef struct threadData_s {
}
#endif

typedef struct {
void (*init)(void);
void* (*malloc)(size_t);
void* (*malloc_atomic)(size_t);
char* (*malloc_string)(size_t);
char* (*malloc_strdup)(const char*);
int (*collect_a_little)(void);
} omc_alloc_interface_t;

extern omc_alloc_interface_t omc_alloc_interface;
extern omc_alloc_interface_t omc_alloc_interface_pooled;

#endif
19 changes: 9 additions & 10 deletions SimulationRuntime/c/simulation/solver/perform_simulation.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ int performSimulation(DATA* data, SOLVER_INFO* solverInfo)
/***** Start main simulation loop *****/
while(solverInfo->currentTime < simInfo->stopTime)
{
omc_alloc_interface.collect_a_little();
#if defined(OMC_OMP)
#pragma omp barrier
#endif
Expand Down Expand Up @@ -196,8 +197,9 @@ int performSimulation(DATA* data, SOLVER_INFO* solverInfo)


/***** Event handling *****/
if(measure_time_flag)
if(measure_time_flag) {
rt_tick(SIM_TIMER_EVENT);
}

eventType = checkEvents(data, solverInfo->eventLst, &(solverInfo->currentTime), solverInfo);
if(eventType > 0)
Expand Down Expand Up @@ -257,19 +259,16 @@ int performSimulation(DATA* data, SOLVER_INFO* solverInfo)
flag = flag && 1 == fwrite(&(data->localData[0]->timeValue), sizeof(double), 1, fmt);
tmpdbl = rt_accumulated(SIM_TIMER_STEP);
flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, fmt);
for(i = 0; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++)
{
for(i = 0; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) {
tmpint = rt_ncall(i + SIM_TIMER_FIRST_FUNCTION);
flag = flag && 1 == fwrite(&tmpint, sizeof(unsigned int), 1, fmt);
}
for(i = 0; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++)
{
for(i = 0; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) {
tmpdbl = rt_accumulated(i + SIM_TIMER_FIRST_FUNCTION);
flag = flag && 1 == fwrite(&tmpdbl, sizeof(double), 1, fmt);
}
rt_accumulate(SIM_TIMER_OVERHEAD);
if(!flag)
{
if (!flag) {
WARNING1(LOG_SOLVER, "Disabled time measurements because the output file could not be generated: %s", strerror(errno));
fclose(fmt);
fmt = NULL;
Expand All @@ -282,10 +281,10 @@ int performSimulation(DATA* data, SOLVER_INFO* solverInfo)
/***** end of Emit this time step *****/

/* save dassl stats before reset */
if(solverInfo->didEventStep == 1 && solverInfo->solverMethod == 3)
{
for(ui = 0; ui < numStatistics; ui++)
if (solverInfo->didEventStep == 1 && solverInfo->solverMethod == 3) {
for(ui = 0; ui < numStatistics; ui++) {
((DASSL_DATA*)solverInfo->solverData)->dasslStatistics[ui] += ((DASSL_DATA*)solverInfo->solverData)->dasslStatisticsTmp[ui];
}
}

/* Check if terminate()=true */
Expand Down
10 changes: 7 additions & 3 deletions SimulationRuntime/c/simulation/solver/solver_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,13 @@ int solver_main(DATA* data, const char* init_initMethod,

/* allocate SolverInfo memory */
retVal = initializeSolverData(data, &solverInfo);

omc_alloc_interface.collect_a_little();

/* initialize all parts of the model */
if(0 == retVal)
if(0 == retVal) {
retVal = initializeModel(data, init_initMethod, init_optiMethod, init_file, init_time, lambda_steps);
}
omc_alloc_interface.collect_a_little();

/* starts the simulation main loop */
if(0 == retVal)
Expand All @@ -574,9 +577,10 @@ int solver_main(DATA* data, const char* init_initMethod,

INFO2(LOG_SOLVER, "Start numerical solver from %g to %g", simInfo->startTime, simInfo->stopTime);
retVal = performSimulation(data, &solverInfo);

omc_alloc_interface.collect_a_little();
/* terminate the simulation */
finishSimulation(data, &solverInfo, outputVariablesAtEnd);
omc_alloc_interface.collect_a_little();
}

/* free SolverInfo memory */
Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/c/util/ModelicaUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ char* ModelicaAllocateString(size_t len) {
}

char* ModelicaAllocateStringWithErrorReturn(size_t len) {
char *res = GC_malloc_atomic(len+1);
char *res = omc_alloc_interface.malloc_string(len+1);
if (res != NULL) {
res[len] = '\0';
}
Expand Down
111 changes: 104 additions & 7 deletions SimulationRuntime/c/util/memory_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,141 @@


#include "memory_pool.h"
#include <string.h>
#include <pthread.h>
#include <gc.h>

omc_alloc_interface_t omc_alloc_interface = {
GC_init,
GC_malloc,
GC_malloc_atomic,
(char*(*)(size_t)) GC_malloc_atomic,
GC_strdup,
GC_collect_a_little
};

typedef struct list_s {
void *memory;
size_t used;
size_t size;
struct list_s *next;
} list;

static pthread_mutex_t memory_pool_mutex = PTHREAD_MUTEX_INITIALIZER;
static list *memory_pools = NULL;

static void pool_init(void)
{
memory_pools = (list*) malloc(sizeof(list));
memory_pools->used = 0;
memory_pools->size = 2*1024*1024; /* 2MB pool by default */
memory_pools->memory = malloc(memory_pools->size);
memory_pools->next = NULL;
}

static unsigned long upper_power_of_two(unsigned long v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}

static inline size_t round_up(size_t num, size_t factor)
{
return num + factor - 1 - (num - 1) % factor;
}

static inline void pool_expand(size_t len)
{
/* Check if we have enough memory already */
if (memory_pools->size - memory_pools->used >= len) {
return;
}
list *newlist = (list*) malloc(sizeof(list));
newlist->next = memory_pools;
memory_pools = newlist;
memory_pools->used = 0;
memory_pools->size = upper_power_of_two(3*memory_pools->next->size/2 + len); /* expand by 1.5x the old memory pool. More if we request a very large array. */
memory_pools->memory = malloc(memory_pools->size);
}

static void* pool_malloc(size_t sz)
{
void *res;
sz = round_up(sz,8);
pthread_mutex_lock(&memory_pool_mutex);
pool_expand(sz);
res = memory_pools->memory + memory_pools->used;
memory_pools->used += sz;
pthread_mutex_unlock(&memory_pool_mutex);
memset(res,0,sz);
return res;
}

static int pool_free(void)
{
list *freelist = memory_pools->next;
while (freelist) {
list *next = freelist->next;
free(freelist->memory);
free(freelist);
freelist = next;
}
memory_pools->used = 0;
memory_pools->next = 0;
return 0;
}

omc_alloc_interface_t omc_alloc_interface_pooled = {
pool_init,
pool_malloc,
pool_malloc,
(char*(*)(size_t)) malloc,
strdup,
pool_free
};

/* allocates n reals in the real_buffer */
m_real* real_alloc(int n)
{
return (m_real*) GC_malloc_atomic(n*sizeof(m_real));
return (m_real*) omc_alloc_interface.malloc_atomic(n*sizeof(m_real));
}

/* allocates n integers in the integer_buffer */
m_integer* integer_alloc(int n)
{
return (m_integer*) GC_malloc_atomic(n*sizeof(m_integer));
return (m_integer*) omc_alloc_interface.malloc_atomic(n*sizeof(m_integer));
}

/* allocates n strings in the string_buffer */
m_string* string_alloc(int n)
{
return (m_string*) GC_malloc_atomic(n*sizeof(m_string));
return (m_string*) omc_alloc_interface.malloc_atomic(n*sizeof(m_string));
}

/* allocates n booleans in the boolean_buffer */
m_boolean* boolean_alloc(int n)
{
return (m_boolean*) GC_malloc_atomic(n*sizeof(m_boolean));
return (m_boolean*) omc_alloc_interface.malloc_atomic(n*sizeof(m_boolean));
}

_index_t* size_alloc(int n)
{
return (_index_t*) GC_malloc_atomic(n*sizeof(_index_t));
return (_index_t*) omc_alloc_interface.malloc_atomic(n*sizeof(_index_t));
}

_index_t** index_alloc(int n)
{
return (_index_t**) GC_malloc(n*sizeof(_index_t*));
return (_index_t**) omc_alloc_interface.malloc(n*sizeof(_index_t*));
}

/* allocates n elements of size sze */
void* generic_alloc(int n, size_t sze)
{
return (void*) GC_malloc(n*sze);
return (void*) omc_alloc_interface.malloc(n*sze);
}
2 changes: 1 addition & 1 deletion SimulationRuntime/c/util/modelica_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ modelica_string_const init_modelica_string(modelica_string_const str)
modelica_string_t alloc_modelica_string(int length)
{
/* Reserve place for null terminator too.*/
modelica_string_t dest = (modelica_string_t) GC_malloc_atomic(length+1);
modelica_string_t dest = (modelica_string_t) omc_alloc_interface.malloc_string(length+1);
if (dest != 0) {
dest[length]=0;
}
Expand Down
4 changes: 2 additions & 2 deletions SimulationRuntime/c/util/real_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,10 +805,10 @@ void cat_alloc_real_array(int k, real_array_t* dest, int n,
}

/* calculate size of sub and super structure in 1-dim data representation */
for(i = 0; i < (k - 1); i++) {
for (i = 0; i < (k - 1); i++) {
n_super *= elts[0]->dim_size[i];
}
for(i = k; i < elts[0]->ndims; i++) {
for (i = k; i < elts[0]->ndims; i++) {
n_sub *= elts[0]->dim_size[i];
}
/* allocate dest structure */
Expand Down

0 comments on commit 971d825

Please sign in to comment.