Changeset: 2a66752740e2 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2a66752740e2
Modified Files:
MonetDB5/src/mal/mal_interpreter.mx
sql/src/common/sql_types.mx
Branch: Oct2010
Log Message:
make sure we use digits from the input type for substring operations
the dataflow interpreter spends lots of time in DFLOWeligible. This
is mostly caused by the variable dependency checking (which are nested loops).
For now this is reduced by keeping the initial assignment statement.
Still src/tests/rdf q3_v.sql runs in 3.5 s, while without dataflow in .5sec.
diffs (198 lines):
diff -r 24132d3b2ff1 -r 2a66752740e2 MonetDB5/src/mal/mal_interpreter.mx
--- a/MonetDB5/src/mal/mal_interpreter.mx Wed Oct 06 11:15:27 2010 +0200
+++ b/MonetDB5/src/mal/mal_interpreter.mx Wed Oct 06 16:26:16 2010 +0200
@@ -595,9 +595,10 @@
MalBlkPtr mb; /* carry the context */
MalStkPtr stk;
int start, stop; /* guarded block under consideration*/
- char *status; /* statements can be blocked on other statements */
+ char *status; /* statements can be blocked on other
statements */
char *blocked; /* blocked, should be created first */
- int *inuse; /* inuse in parallel threads reference
count */
+ int *assign; /* first assignment of variable */
+ int *inuse; /* inuse in parallel threads reference count */
queue *done; /* work finished */
queue *todo; /* pending actions for this client */
int nway; /* number of workers */
@@ -1170,7 +1171,6 @@
DFLOWinit(DataFlow flow, FlowStep fs)
{
int i, n;
- char *assign= (char*) GDKzalloc(sizeof(char) * flow->mb->vtop);
PARDEBUG
printf("Initialize dflow block\n");
@@ -1191,8 +1191,11 @@
for (j=0; j<p->argc; j++){
a = getArg(p, j);
- if (j<p->retc && assign[a] == 0 && flow->inuse[a] == 0)
{
- assign[a] = i;
+ if (j<p->retc && flow->assign[a] != 0)
+ assert(0);
+
+ if (j<p->retc && flow->assign[a] == 0 && flow->inuse[a]
== 0) {
+ flow->assign[a] = i;
flow->blocked[a] = isNotUsedIn(p,p->retc,a)?1:0;
}
@@ -1205,13 +1208,12 @@
flow->inuse[i] = 0;
PARDEBUG
for (i=0; i < flow->mb->vtop; i++)
- if ( flow->blocked[i] || flow->inuse[i] || assign[i] ){
+ if ( flow->blocked[i] || flow->inuse[i] || flow->assign[i] ){
printf("%s %d %d [ %1d %2d ]\n", getVarName(flow->mb,i),
getEndOfLife(flow->mb,i), i,
flow->blocked[i],
flow->inuse[i]);
}
- GDKfree(assign);
}
@-
The liberal use of MAL to construct programs complicate proper dataflow
@@ -1237,28 +1239,29 @@
(void) pc;
for(j=0; j<p->argc && !blocked; j++) {
- if ( j >= p->retc && flow->blocked[getArg(p,j)] )
+ int var = getArg(p,j);
+ if ( j >= p->retc && flow->blocked[var] )
blocked++;
- if (j < p->retc && flow->inuse[getArg(p,j)] )
+ if (j < p->retc && flow->inuse[var] )
blocked++;
else
- if ( getEndOfLife(flow->mb,getArg(p,j)) == fs[i].pc ) {
+ if ( getEndOfLife(flow->mb,var) == fs[i].pc ) {
/* make sure all instructions interested have already
been executed */
/* and the eoscope variables are not used anymore */
- blocked += flow->inuse[getArg(p,j)] != 0;
+ blocked += flow->inuse[var] != 0;
for ( k=0; k < i && !blocked; k++)
if (fs[k].status != DFLOWwrapup && fs[k].pc >= 0 ) /*
pc = -1 could be the case before wrapup is set*/
- blocked += !isNotUsedIn(getInstrPtr(flow->mb,
fs[k].pc), 0, getArg(p,j));
+ blocked += !isNotUsedIn(getInstrPtr(flow->mb,
fs[k].pc), 0, var);
} else {
/* handle the dependencies sketched above */
/* search the statement that assigns a value to the
argument or target */
/* it should have been finished already */
- for (l = i-1 ; l >= 0 && !blocked; l--)
+ for (l = i-1 ; l >= flow->assign[var] && !blocked; l--)
if ( fs[l].status != DFLOWwrapup && fs[l].pc >= 0){
q= getInstrPtr(flow->mb, fs[l].pc);
for ( k=0; k < q->retc && !blocked; k++)
- if ( getArg(q,k) == getArg(p,j) )
+ if ( getArg(q,k) == var )
blocked = 1;
}
}
@@ -1483,12 +1486,14 @@
flow->status = (char*) GDKzalloc((stoppc-startpc+1));
flow->blocked = (char*) GDKzalloc(sizeof(char)*mb->vtop);
+ flow->assign = (int*) GDKzalloc(sizeof(int)*mb->vtop);
flow->inuse = (int*) GDKzalloc(sizeof(int)*mb->vtop);
mal_unset_lock(mal_contextLock, "runMALdataflow");
ret = DFLOWscheduler(flow);
GDKfree(flow->status);
GDKfree(flow->blocked);
+ GDKfree(flow->assign);
GDKfree(flow->inuse);
mal_set_lock(mal_contextLock, "runMALdataflow");
flow->free = flows;
diff -r 24132d3b2ff1 -r 2a66752740e2 sql/src/common/sql_types.mx
--- a/sql/src/common/sql_types.mx Wed Oct 06 11:15:27 2010 +0200
+++ b/sql/src/common/sql_types.mx Wed Oct 06 16:26:16 2010 +0200
@@ -497,16 +497,16 @@
}
int
-is_subtype(sql_subtype *t1, sql_subtype *t2)
-/* returns true if t1 is a sub type of t2 */
+is_subtype(sql_subtype *sub, sql_subtype *super)
+/* returns true if sub is a sub type of super */
{
- if (!t1 || !t2)
+ if (!sub || !super)
return 0;
- if (t2->digits > 0 && t1->digits > t2->digits)
+ if (super->digits > 0 && sub->digits > super->digits)
return 0;
/* subtypes are only equal iff
they map onto the same systemtype */
- return (type_cmp(t1->type, t2->type) == 0);
+ return (type_cmp(sub->type, super->type) == 0);
}
char *
@@ -783,7 +783,7 @@
if (strcmp(f->base.name, sqlfname) == 0) {
if (list_length(f->ops) == nrargs && is_subtype(tp,
&((sql_arg *) f->ops->h->data)->type)) {
- unsigned int scale = 0;
+ unsigned int scale = 0, digits;
sql_subfunc *fres = ZNEW(sql_subfunc);
sql_ref_init(&(fres->ref));
@@ -791,7 +791,10 @@
/* same scale as the input */
if (tp && tp->scale > scale)
scale = tp->scale;
- sql_init_subtype(&fres->res, f->res.type,
f->res.digits, scale);
+ digits = f->res.digits;
+ if (tp && f->fix_scale == INOUT)
+ digits = tp->digits;
+ sql_init_subtype(&fres->res, f->res.type,
digits, scale);
return fres;
}
}
@@ -854,12 +857,13 @@
continue;
if (strcmp(f->base.name, sqlfname) == 0) {
if (list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) ==
0) {
- unsigned int scale = 0;
+ unsigned int scale = 0, digits;
sql_subfunc *fres = ZNEW(sql_subfunc);
sql_ref_init(&(fres->ref));
fres->func = f;
/* fix the scale */
+ digits = f->res.digits;
if (f->fix_scale > SCALE_NONE) {
for (n = ops->h; n; n = n->next) {
sql_subtype *a = n->data;
@@ -867,6 +871,8 @@
/* same scale as the input */
if (a && a->scale > scale)
scale = a->scale;
+ if (a && f->fix_scale == INOUT)
+ digits = a->digits;
}
} else if (f->res.scale)
scale = f->res.scale;
@@ -880,9 +886,9 @@
a = n->data;
}
}
- sql_init_subtype(&fres->res, a->type,
f->res.digits, scale);
+ sql_init_subtype(&fres->res, a->type,
digits, scale);
} else {
- sql_init_subtype(&fres->res,
f->res.type, f->res.digits, scale);
+ sql_init_subtype(&fres->res,
f->res.type, digits, scale);
}
return fres;
}
@@ -1627,8 +1633,8 @@
for (t = strings; t < numerical; t++) {
sql_create_func("locate", "str", "locate", *t, *t, INT,
SCALE_NONE);
sql_create_func3("locate", "str", "locate", *t, *t, INT, INT,
SCALE_NONE);
- sql_create_func("substring", "str", "substring", *t, INT, *t,
SCALE_NONE);
- sql_create_func3("substring", "str", "substring", *t, INT, INT,
*t, SCALE_NONE);
+ sql_create_func("substring", "str", "substring", *t, INT, *t,
INOUT);
+ sql_create_func3("substring", "str", "substring", *t, INT, INT,
*t, INOUT);
sql_create_func("like", "str", "like", *t, *t, BIT, SCALE_NONE);
sql_create_func3("like", "str", "like", *t, *t, *t, BIT,
SCALE_NONE);
sql_create_func("ilike", "str", "ilike", *t, *t, BIT,
SCALE_NONE);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list