Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
Improve report of used size of MM datatypes
Browse files Browse the repository at this point in the history
We now collect both how many bytes we want to allocate and how much
memory libGC will consume and report this when reportSerializedSize
is used.

Also fixed a bug where the incorrect size was calculated for the GC
overhead: GC uses 1 byte internally so a 15-byte allocation allocates
a single 16-byte granule whereas a 16-byte allocation allocates 2 16-
byte granules. This accounts for a 20% overhead that was not accounted
for previously.

Belonging to [master]:
  - #2228
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Feb 23, 2018
1 parent 419eaa1 commit bf329a1
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 42 deletions.
18 changes: 9 additions & 9 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -202,7 +202,7 @@ algorithm
ExecStat.execStat("FrontEnd - scodeFlatten");
end if;
(cache,env) = Builtin.initialGraph(cache);
env_1 = FGraphBuildEnv.mkProgramGraph(cdecls, FCore.USERDEFINED(), env);
env = FGraphBuildEnv.mkProgramGraph(cdecls, FCore.USERDEFINED(), env);

// set the source of this element
source = ElementSource.addElementSourcePartOfOpt(DAE.emptyElementSource, FGraph.getScopePath(env));
Expand All @@ -212,15 +212,15 @@ algorithm
end if;
ExecStat.execStat("FrontEnd - mkProgramGraph");

(cache,env_2,ih,dae2) = instClassInProgram(cache, env_1, ih, cdecls, path, source);
(cache,env,ih,dae2) = instClassInProgram(cache, env, ih, cdecls, path, source);
// check the models for balancing
//Debug.fcall2(Flags.CHECK_MODEL_BALANCE, checkModelBalancing, SOME(path), dae1);
//Debug.fcall2(Flags.CHECK_MODEL_BALANCE, checkModelBalancing, SOME(path), dae2);

// let the GC collect these as they are used only by Inst!
releaseInstHashTable();
then
(cache,env_2,ih,dae2);
(cache,env,ih,dae2);

// class in package
case (cache,ih,(cdecls as (_ :: _)),(path as Absyn.QUALIFIED()))
Expand All @@ -240,13 +240,13 @@ algorithm

//System.startTimer();
//print("\nInstClassDecls");
env_1 = FGraphBuildEnv.mkProgramGraph(cdecls, FCore.USERDEFINED(), env);
env = FGraphBuildEnv.mkProgramGraph(cdecls, FCore.USERDEFINED(), env);
//System.stopTimer();
//print("\nInstClassDecls: " + realString(System.getTimerIntervalTime()));

//System.startTimer();
//print("\nLookupClass");
(cache,(cdef as SCode.CLASS(name = n)),env_2) = Lookup.lookupClass(cache, env_1, path, SOME(Absyn.dummyInfo));
(cache,(cdef as SCode.CLASS(name = n)),env) = Lookup.lookupClass(cache, env, path, SOME(Absyn.dummyInfo));

//System.stopTimer();
//print("\nLookupClass: " + realString(System.getTimerIntervalTime()));
Expand All @@ -258,16 +258,16 @@ algorithm
end if;
ExecStat.execStat("FrontEnd - mkProgramGraph");

(cache,env_2,ih,_,dae,_,_,_,_,_) = instClass(cache,env_2,ih,
UnitAbsynBuilder.emptyInstStore(),DAE.NOMOD(), makeTopComponentPrefix(env_2, n), cdef,
(cache,env,ih,_,dae,_,_,_,_,_) = instClass(cache,env,ih,
UnitAbsynBuilder.emptyInstStore(),DAE.NOMOD(), makeTopComponentPrefix(env, n), cdef,
{}, false, InstTypes.TOP_CALL(), ConnectionGraph.EMPTY, Connect.emptySet) "impl";
//System.stopTimer();
//print("\nInstClass: " + realString(System.getTimerIntervalTime()));

//System.startTimer();
//print("\nReEvaluateIf");
//print(" ********************** backpatch 1 **********************\n");
dae = InstUtil.reEvaluateInitialIfEqns(cache,env_2,dae,true);
dae = InstUtil.reEvaluateInitialIfEqns(cache,env,dae,true);
//System.stopTimer();
//print("\nReEvaluateIf: " + realString(System.getTimerIntervalTime()));

Expand All @@ -287,7 +287,7 @@ algorithm
// let the GC collect these as they are used only by Inst!
releaseInstHashTable();
then
(cache, env_2, ih, dae);
(cache, env, ih, dae);

end match;
end instantiateClass_dispatch;
Expand Down
41 changes: 14 additions & 27 deletions Compiler/SimCode/SimCodeMain.mo
Expand Up @@ -767,6 +767,7 @@ algorithm
String fmiVersion;
BackendDAE.SymbolicJacobians fmiDer;
DAE.FunctionTree funcs;
list<Option<Integer>> allRoots;

case (graph, _, filenameprefix, _, _, _) algorithm
// calculate stuff that we need to create SimCode data structure
Expand All @@ -777,33 +778,16 @@ algorithm
SOME(dae1) := odae;

if Flags.isSet(Flags.SERIALIZED_SIZE) then
serializeNotify(getGlobalRoot(Global.instHashIndex), "Global.instHash");
try
serializeNotify(getGlobalRoot(Global.builtinEnvIndex), "Global.builtinIndex");
else
end try;
try
serializeNotify(getGlobalRoot(Global.rewriteRulesIndex), "Global.rewriteRulesIndex");
else
end try;
try
serializeNotify(getGlobalRoot(Global.inlineHashTable), "Global.inlineHashTable");
else
end try;
try
serializeNotify(getGlobalRoot(Global.operatorOverloadingCache), "Global.operatorOverloadingCache");
else
end try;
try
serializeNotify(getGlobalRoot(Global.interactiveCache), "Global.interactiveCache");
else
end try;
allRoots := {};
for i in 1:300 loop
try
allRoots := getGlobalRoot(i)::allRoots;
else
end try;
end for;
serializeNotify(allRoots, "All local+global roots (1:300)");
serializeNotify(dae1, "FrontEnd DAE");
serializeNotify(graph, "FCore.Graph");
serializeNotify((graph,inEnv), "FCore.Graph + Old graph");
serializeNotify(cache, "FCore.Cache");
serializeNotify((cache,inCache), "FCore.Cache + Old cache");
serializeNotify(SymbolTable.get(), "Symbol Table (Absyn and SCode)");
serializeNotify((graph,inEnv,cache,inCache), "FCore.Graph + Cache + Old graph + Old cache");
serializeNotify((SymbolTable.get(),dae1,graph,inEnv,cache,inCache), "Symbol Table, DAE, Graph, OldGraph, Cache, OldCache");
ExecStat.execStat("Serialize FrontEnd");
end if;
Expand Down Expand Up @@ -1332,8 +1316,11 @@ end generateModelCodeDAE;
protected function serializeNotify<T>
input T data;
input String name;
protected
Real sz,raw_sz;
algorithm
Error.addMessage(Error.SERIALIZED_SIZE, {name, StringUtil.bytesToReadableUnit(System.getSizeOfData(data))});
(sz,raw_sz) := System.getSizeOfData(data);
Error.addMessage(Error.SERIALIZED_SIZE, {name, StringUtil.bytesToReadableUnit(sz), StringUtil.bytesToReadableUnit(raw_sz)});
end serializeNotify;

annotation(__OpenModelica_Interface="backend");
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Util/Error.mo
Expand Up @@ -1021,7 +1021,7 @@ public constant Message UNIONTYPE_MISSING_TYPEVARS = MESSAGE(5044, TRANSLATION()
public constant Message UNIONTYPE_WRONG_NUM_TYPEVARS = MESSAGE(5045, TRANSLATION(), ERROR(),
Util.gettext("Uniontype %s has %s type variables, but got %s."));
public constant Message SERIALIZED_SIZE = MESSAGE(5046, TRANSLATION(), NOTIFICATION(),
Util.gettext("%s uses %s of memory."));
Util.gettext("%s uses %s of memory (%s without GC overhead)."));

public constant Message COMPILER_ERROR = MESSAGE(5999, TRANSLATION(), ERROR(),
Util.notrans("%s"));
Expand Down
3 changes: 2 additions & 1 deletion Compiler/Util/System.mo
Expand Up @@ -1310,7 +1310,8 @@ end updateUriMapping;
function getSizeOfData<T>
input T data;
output Real sz;
external "C" sz=SystemImpl__getSizeOfData(data) annotation(Library = {"omcruntime"}, Documentation(info="<html>
output Real raw_sz "The size without granule overhead";
external "C" sz=SystemImpl__getSizeOfData(data, raw_sz) annotation(Library = {"omcruntime"}, Documentation(info="<html>
Counts the number of bytes that were allocated to hold the given data structure.
Includes constant data and handles cycles.
</html>"));
Expand Down
14 changes: 10 additions & 4 deletions Compiler/runtime/systemimplmisc.cpp
Expand Up @@ -48,14 +48,16 @@ extern "C" {

static inline size_t actualByteSize(size_t sz)
{
/* GC uses 2 words as the minimum allocation unit: a granule */
size_t res = GC_GRANULE_BYTES*((sz+GC_GRANULE_BYTES-1) / GC_GRANULE_BYTES);
/* GC uses 2 words as the minimum allocation unit: a granule
* GC also uses up 1 byte of the allocation for its internal use.
*/
size_t res = GC_GRANULE_BYTES*((sz+GC_GRANULE_BYTES-1+1) / GC_GRANULE_BYTES);
return res;
}
#include <stdio.h>
double SystemImpl__getSizeOfData(void *data)
double SystemImpl__getSizeOfData(void *data, double *raw_size_res)
{
size_t sz=0;
size_t sz=0, raw_sz=0;
std::set<void*> handled;
std::stack<void*> work;
work.push(data);
Expand All @@ -76,16 +78,19 @@ double SystemImpl__getSizeOfData(void *data)
continue;
}
if (hdr==MMC_REALHDR) {
raw_sz += sizeof(void*)+sizeof(double);
sz += actualByteSize(sizeof(void*)+sizeof(double));
continue;
}
if (MMC_HDRISSTRING(hdr)) {
raw_sz += sizeof(void*)+MMC_STRLEN(item)+1;
sz += actualByteSize(sizeof(void*)+MMC_STRLEN(item)+1);
continue;
}
if (MMC_HDRISSTRUCT(hdr)) {
mmc_uint_t slots = MMC_HDRSLOTS(hdr);
mmc_uint_t ctor = MMC_HDRCTOR(hdr);
raw_sz += sizeof(void*)*(slots+1);
sz += actualByteSize(sizeof(void*)*(slots+1));
// Push the sub-objects to the stack
for (int i = (ctor>=3 && ctor != MMC_ARRAY_TAG) ? 2 /* MM record description */ : 1; i <= slots; i++) {
Expand All @@ -98,6 +103,7 @@ fprintf(stderr, "abort... bytes=%d num items=%d\n", sz, handled.size());
printAny(item);
abort();
}
*raw_size_res = raw_sz;
return sz;
}

Expand Down

0 comments on commit bf329a1

Please sign in to comment.