Changeset: b0e2acf99f2f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b0e2acf99f2f
Modified Files:
        gdk/gdk_select.c
Branch: Jun2020
Log Message:

Speed up imprints check for dense candidate lists.
Thanks lots to Nenya Edjah for the report and the core of the change.
This fixes bug 6847.


diffs (213 lines):

diff --git a/gdk/gdk_select.c b/gdk/gdk_select.c
--- a/gdk/gdk_select.c
+++ b/gdk/gdk_select.c
@@ -165,8 +165,8 @@ hashselect(BAT *b, struct canditer *rest
 
 /* Imprints select code */
 
-/* inner check */
-#define impscheck(canditer_next,TEST,ADD)                              \
+/* inner check, non-dense canditer */
+#define impscheck(TEST,ADD)                                            \
        do {                                                            \
                const oid e = (oid) (i+limit-pr_off+hseq);              \
                if (im[icnt] & mask) {                                  \
@@ -195,13 +195,43 @@ hashselect(BAT *b, struct canditer *rest
                }                                                       \
        } while (false)
 
+/* inner check, dense canditer */
+#define impscheck_dense(TEST,ADD)                                      \
+       do {                                                            \
+               const oid e = (oid) (i+limit-pr_off+hseq);              \
+               if (im[icnt] & mask) {                                  \
+                       if ((im[icnt] & ~innermask) == 0) {             \
+                               while (p < ci->ncand && o < e) {        \
+                                       v = src[o-hseq];                \
+                                       ADD;                            \
+                                       cnt++;                          \
+                                       p++;                            \
+                                       o = canditer_next_dense(ci);    \
+                               }                                       \
+                       } else {                                        \
+                               while (p < ci->ncand && o < e) {        \
+                                       v = src[o-hseq];                \
+                                       ADD;                            \
+                                       cnt += (TEST) != 0;             \
+                                       p++;                            \
+                                       o = canditer_next_dense(ci);    \
+                               }                                       \
+                       }                                               \
+               } else {                                                \
+                       BUN skip_sz = MIN(ci->ncand - p, e - o);        \
+                       p += skip_sz;                                   \
+                       o += skip_sz;                                   \
+                       ci->next += skip_sz;                            \
+               }                                                       \
+       } while (false)
+
 /* main loop for imprints */
 /*
  * icnt is the iterator for imprints
  * dcnt is the iterator for dictionary entries
  * i    is the iterator for the values in imprints
  */
-#define impsloop(canditer_next,TEST,ADD)                               \
+#define impsloop(ISDENSE,TEST,ADD)                                     \
        do {                                                            \
                BUN dcnt, icnt, limit, i;                               \
                const cchdc_t *restrict d = (cchdc_t *) imprints->dict; \
@@ -227,12 +257,12 @@ hashselect(BAT *b, struct canditer *rest
                                for (;                                  \
                                     icnt < l && i <= w - hseq + pr_off; \
                                     icnt++) {                          \
-                                       impscheck(canditer_next,TEST,ADD); \
+                                       impscheck##ISDENSE(TEST,ADD);   \
                                        i += limit;                     \
                                }                                       \
                        }                                               \
                        else {                                          \
-                               impscheck(canditer_next,TEST,ADD);      \
+                               impscheck##ISDENSE(TEST,ADD);           \
                                i += limit;                             \
                                icnt++;                                 \
                        }                                               \
@@ -246,7 +276,7 @@ hashselect(BAT *b, struct canditer *rest
        } while (false)
 
 /* construct the mask */
-#define impsmask(canditer_next,TEST,B)                                 \
+#define impsmask(ISDENSE,TEST,B)                                       \
        do {                                                            \
                const uint##B##_t *restrict im = (uint##B##_t *) 
imprints->imps; \
                uint##B##_t mask = 0, innermask;                        \
@@ -275,13 +305,13 @@ hashselect(BAT *b, struct canditer *rest
                        innermask = IMPSunsetBit(B, innermask, 0);      \
                                                                        \
                if (BATcapacity(bn) < maximum) {                        \
-                       impsloop(canditer_next, TEST,                   \
+                       impsloop(ISDENSE, TEST,                         \
                                 buninsfix(bn, dst, cnt, o,             \
                                           (BUN) ((dbl) cnt / (dbl) (p == 0 ? 1 
: p) \
                                                  * (dbl) (ci->ncand-p) * 1.1 + 
1024), \
                                           BATcapacity(bn) + ci->ncand - p, 
BUN_NONE)); \
                } else {                                                \
-                       impsloop(canditer_next, TEST, quickins(dst, cnt, o, 
bn)); \
+                       impsloop(ISDENSE, TEST, quickins(dst, cnt, o, bn)); \
                }                                                       \
        } while (false)
 
@@ -307,15 +337,15 @@ hashselect(BAT *b, struct canditer *rest
        } while (false)
 
 /* choose number of bits */
-#define bitswitch(canditer_next, TEST, TYPE)                           \
+#define bitswitch(ISDENSE, TEST, TYPE)                                 \
        do {                                                            \
                assert(imprints);                                       \
-               *algo = "imprints select " #TEST " (" #canditer_next ")"; \
+               *algo = "imprints select " #TEST " (canditer_next" #ISDENSE 
")"; \
                switch (imprints->bits) {                               \
-               case 8:  checkMINMAX(8, TYPE); impsmask(canditer_next,TEST,8); 
break; \
-               case 16: checkMINMAX(16, TYPE); 
impsmask(canditer_next,TEST,16); break; \
-               case 32: checkMINMAX(32, TYPE); 
impsmask(canditer_next,TEST,32); break; \
-               case 64: checkMINMAX(64, TYPE); 
impsmask(canditer_next,TEST,64); break; \
+               case 8:  checkMINMAX(8, TYPE); impsmask(ISDENSE,TEST,8); break; 
\
+               case 16: checkMINMAX(16, TYPE); impsmask(ISDENSE,TEST,16); 
break; \
+               case 32: checkMINMAX(32, TYPE); impsmask(ISDENSE,TEST,32); 
break; \
+               case 64: checkMINMAX(64, TYPE); impsmask(ISDENSE,TEST,64); 
break; \
                default: assert(0); break;                              \
                }                                                       \
        } while (false)
@@ -398,17 +428,17 @@ hashselect(BAT *b, struct canditer *rest
 #define MAXVALUEflt    GDK_flt_max
 #define MAXVALUEdbl    GDK_dbl_max
 
-#define choose(NAME, canditer_next, TEST, TYPE)                        \
-       do {                                                    \
-               if (use_imprints) {                             \
-                       bitswitch(canditer_next, TEST, TYPE);   \
-               } else {                                        \
-                       scanloop(NAME, canditer_next, TEST);    \
-               }                                               \
+#define choose(NAME, ISDENSE, TEST, TYPE)                              \
+       do {                                                            \
+               if (use_imprints) {                                     \
+                       bitswitch(ISDENSE, TEST, TYPE);                 \
+               } else {                                                \
+                       scanloop(NAME, canditer_next##ISDENSE, TEST);   \
+               }                                                       \
        } while (false)
 
 /* definition of type-specific core scan select function */
-#define scanfunc(NAME, TYPE, canditer_next)                            \
+#define scanfunc(NAME, TYPE, ISDENSE)                                  \
 static BUN                                                             \
 NAME##_##TYPE(BAT *b, struct canditer *restrict ci, BAT *bn,           \
              const TYPE *tl, const TYPE *th, bool li, bool hi,         \
@@ -452,21 +482,21 @@ NAME##_##TYPE(BAT *b, struct canditer *r
        if (equi) {                                                     \
                assert(!use_imprints);                                  \
                if (lnil)                                               \
-                       scanloop(NAME, canditer_next, is_##TYPE##_nil(v)); \
+                       scanloop(NAME, canditer_next##ISDENSE, 
is_##TYPE##_nil(v)); \
                else                                                    \
-                       scanloop(NAME, canditer_next, v == vl);         \
+                       scanloop(NAME, canditer_next##ISDENSE, v == vl); \
        } else if (anti) {                                              \
                if (b->tnonil) {                                        \
-                       choose(NAME, canditer_next, (v <= vl || v >= vh), 
TYPE); \
+                       choose(NAME, ISDENSE, (v <= vl || v >= vh), TYPE); \
                } else {                                                \
-                       choose(NAME, canditer_next, !is_##TYPE##_nil(v) && (v 
<= vl || v >= vh), TYPE); \
+                       choose(NAME, ISDENSE, !is_##TYPE##_nil(v) && (v <= vl 
|| v >= vh), TYPE); \
                }                                                       \
        } else if (b->tnonil && vl == minval) {                         \
-               choose(NAME, canditer_next, v <= vh, TYPE);             \
+               choose(NAME, ISDENSE, v <= vh, TYPE);                   \
        } else if (vh == maxval) {                                      \
-               choose(NAME, canditer_next, v >= vl, TYPE);             \
+               choose(NAME, ISDENSE, v >= vl, TYPE);                   \
        } else {                                                        \
-               choose(NAME, canditer_next, v >= vl && v <= vh, TYPE);  \
+               choose(NAME, ISDENSE, v >= vl && v <= vh, TYPE);        \
        }                                                               \
        return cnt;                                                     \
 }
@@ -633,23 +663,23 @@ fullscan_str(BAT *b, struct canditer *re
 
 /* scan select type switch */
 #ifdef HAVE_HGE
-#define scanfunc_hge(NAME, canditer_next)      \
-       scanfunc(NAME, hge, canditer_next)
+#define scanfunc_hge(NAME, ISDENSE)            \
+       scanfunc(NAME, hge, ISDENSE)
 #else
-#define scanfunc_hge(NAME, canditer_next)
+#define scanfunc_hge(NAME, ISDENSE)
 #endif
-#define scan_sel(NAME, canditer_next)          \
-       scanfunc(NAME, bte, canditer_next)      \
-       scanfunc(NAME, sht, canditer_next)      \
-       scanfunc(NAME, int, canditer_next)      \
-       scanfunc(NAME, flt, canditer_next)      \
-       scanfunc(NAME, dbl, canditer_next)      \
-       scanfunc(NAME, lng, canditer_next)      \
-       scanfunc_hge(NAME, canditer_next)
+#define scan_sel(NAME, ISDENSE)                        \
+       scanfunc(NAME, bte, ISDENSE)            \
+       scanfunc(NAME, sht, ISDENSE)            \
+       scanfunc(NAME, int, ISDENSE)            \
+       scanfunc(NAME, flt, ISDENSE)            \
+       scanfunc(NAME, dbl, ISDENSE)            \
+       scanfunc(NAME, lng, ISDENSE)            \
+       scanfunc_hge(NAME, ISDENSE)
 
 /* scan/imprints select */
-scan_sel(fullscan, canditer_next)
-scan_sel(densescan, canditer_next_dense)
+scan_sel(fullscan, )
+scan_sel(densescan, _dense)
 
 
 static BAT *
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to