Changeset: 623b983b2c6f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/623b983b2c6f
Modified Files:
monetdb5/optimizer/opt_dataflow.c
Branch: parappend
Log Message:
Refactored opt_dataflow logic
Seems to work as long as we keep the actual dataflow_regions disabled.
diffs (262 lines):
diff --git a/monetdb5/optimizer/opt_dataflow.c
b/monetdb5/optimizer/opt_dataflow.c
--- a/monetdb5/optimizer/opt_dataflow.c
+++ b/monetdb5/optimizer/opt_dataflow.c
@@ -49,8 +49,24 @@ typedef char *States;
#define setState(S,P,K,F) ( assert(getArg(P,K) < vlimit), (S)[getArg(P,K)] |=
F)
#define getState(S,P,K) ((S)[getArg(P,K)])
+typedef enum {
+ no_region,
+ singleton_region, // only ever a single statement
+ dataflow_region, // statements without side effects, in parallel
+ existing_region, // existing barrier..exit region, copied as-is
+} region_type;
+
+typedef struct {
+ region_type type;
+ union {
+ struct {
+ int level; // level of nesting
+ } existing_region;
+ } st;
+} region_state;
+
static int
-simpleFlow(InstrPtr *old, int start, int last)
+simpleFlow(InstrPtr *old, int start, int last, region_state *state)
{
int i, j, k, simple = TRUE;
InstrPtr p = NULL, q;
@@ -58,6 +74,8 @@ simpleFlow(InstrPtr *old, int start, int
/* ignore trivial blocks */
if ( last - start == 1)
return TRUE;
+ if ( state->type == existing_region )
+ return TRUE;
/* skip sequence of simple arithmetic first */
for( ; simple && start < last; start++)
if ( old[start] ) {
@@ -149,6 +167,60 @@ dflowGarbagesink(Client cntxt, MalBlkPtr
return top;
}
+static bool
+checkBreakpoint(Client cntxt, MalBlkPtr mb, InstrPtr p, States states,
region_state *state)
+{
+ switch (state->type) {
+ case singleton_region:
+ return true;
+ case dataflow_region:
+ return dataflowBreakpoint(cntxt, mb, p, states);
+ case existing_region:
+ if (state->st.existing_region.level == 0) {
+ // previous statement ended the region
+ return true;
+ }
+ if (blockStart(p)) {
+ state->st.existing_region.level += 1;
+ } else if (blockExit(p)) {
+ state->st.existing_region.level -= 1;
+ }
+ return false;
+ default:
+ // serious corruption has occurred.
+ assert(0 && "corrupted region_type");
+ abort();
+ }
+ assert(0 && "unreachable");
+ return true;
+}
+
+static void
+decideRegionType(Client cntxt, MalBlkPtr mb, InstrPtr p, region_state *state)
+{
+ (void) cntxt;
+
+ if (blockStart(p)) {
+ state->type = existing_region;
+ state->st.existing_region.level = 1;
+ } else if (p->token == ENDsymbol) {
+ state->type = existing_region;
+ } else if (p->barrier) {
+ state->type = singleton_region;
+ } else if (isUnsafeFunction(p)) {
+ state->type = singleton_region;
+ } else if (hasSideEffects(mb, p, false)) {
+ state->type = singleton_region;
+ } else if (isMultiplex(p)) {
+ state->type = singleton_region;
+ } else {
+ // turn this into dataflow_region, if you dare
+ (void)42;
+ state->type = singleton_region;
+ }
+}
+
+
/* dataflow blocks are transparent, because they are always
executed, either sequentially or in parallel */
@@ -156,15 +228,38 @@ static str
OPTdataflowImplementation_wrapped(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr p)
{
volatile int interesting_banana = 0;
- int i,j,k, start=1, slimit, breakpoint, actions=0, simple = TRUE;
+ int i,j,k, start, slimit, breakpoint, actions=0, simple = TRUE;
int flowblock= 0;
InstrPtr *sink = NULL, *old = NULL, q;
int limit, vlimit, top = 0;
States states;
char buf[256];
+ region_state state = { singleton_region };
lng usec = GDKusec();
str msg = MAL_SUCCEED;
+
+ do {
+ if (mb->stop < 2)
+ break;
+ InstrPtr p = mb->stmt[1];
+
+ if (p->argc < 2)
+ break;
+
+ if (p->modname != querylogRef || p->fcnname != defineRef)
+ break;
+
+ const char *txt = getVarConstant(mb, getArg(p,1)).val.sval;
+ if (strstr(txt, "value / 2") != 0)
+ interesting_banana = 1;
+ } while (0);
+
+ // if (!interesting_banana)
+ // return MAL_SUCCEED;
+
+
+
/* don't use dataflow on single processor systems */
if (GDKnr_threads <= 1)
return MAL_SUCCEED;
@@ -186,22 +281,6 @@ OPTdataflowImplementation_wrapped(Client
setVariableScope(mb);
- do {
- if (mb->stop < 2)
- break;
- InstrPtr p = mb->stmt[1];
-
- if (p->argc < 2)
- break;
-
- if (p->modname != querylogRef || p->fcnname != defineRef)
- break;
-
- const char *txt = getVarConstant(mb, getArg(p,1)).val.sval;
- if (strstr(txt, "value / 2") != 0)
- interesting_banana = 1;
- } while (0);
-
limit= mb->stop;
slimit= mb->ssize;
old = mb->stmt;
@@ -210,16 +289,17 @@ OPTdataflowImplementation_wrapped(Client
actions = -1;
goto wrapup;
}
- pushInstruction(mb,old[0]);
/* inject new dataflow barriers using a single pass through the program
*/
+ start = 0;
+ state.type = singleton_region;
for (i = 1; i<limit; i++) {
p = old[i];
assert(p);
- breakpoint = dataflowBreakpoint(cntxt, mb, p ,states);
+ breakpoint = checkBreakpoint(cntxt, mb, p, states, &state);
if ( breakpoint ){
/* close previous flow block */
- simple = simpleFlow(old,start,i);
+ simple = simpleFlow(old,start,i, &state);
if ( !simple){
flowblock = newTmpVariable(mb,TYPE_bit);
@@ -254,37 +334,14 @@ OPTdataflowImplementation_wrapped(Client
pushInstruction(mb,old[i]);
break;
}
- // implicitly a new flow block starts unless we have a
hard side-effect
+
+ // Start a new region
memset((char*) states, 0, vlimit * sizeof(char));
top = 0;
- if ( p->token == ENDsymbol ||
(hasSideEffects(mb,p,FALSE) && !blockStart(p)) || isMultiplex(p)){
- start = i+1;
- pushInstruction(mb,p);
- continue;
- }
start = i;
+ decideRegionType(cntxt, mb, p, &state);
}
- if (blockStart(p)){
- /* barrier blocks are kept out of the dataflow */
- /* assumes that barrier entry/exit pairs are correct. */
- /* A refinement is parallelize within a barrier block */
- int copy= 1;
- pushInstruction(mb,p);
- for ( i++; i<limit; i++) {
- p = old[i];
- pushInstruction(mb,p);
-
- if (blockStart(p))
- copy++;
- if (blockExit(p)) {
- copy--;
- if ( copy == 0) break;
- }
- }
- // reset admin
- start = i+1;
- }
// remember you assigned/read variables
for ( k = 0; k < p->retc; k++)
setState(states, p, k, VARWRITE);
@@ -299,6 +356,7 @@ OPTdataflowImplementation_wrapped(Client
setState(states, p ,k, VARREAD);
}
}
+
/* take the remainder as is */
for (; i<slimit; i++)
if (old[i])
@@ -331,22 +389,19 @@ wrapup:
static stream *
open_trace_stream(void)
{
- char path[4096];
+ char path[4096] = {0};
stream *s = NULL;
- do {
-
- char *tst_trace_dir = getenv("JOERITRACE");
- if (!tst_trace_dir)
- break;
-
+ char *tst_trace_dir = getenv("JOERITRACE");
+ if (tst_trace_dir) {
long t = time(NULL);
int p = getpid();
sprintf(path, "%s/trace.%ld.%d.log", tst_trace_dir, t, p);
+ } else {
+ strcpy(path, "a");
+ }
- s = open_wastream(path);
- } while (0);
-
+ s = open_wastream(path);
return s;
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list