Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Avoid memcpy while retrieving data from dynars (speed up)
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 7 Oct 2004 09:42:27 +0000 (09:42 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 7 Oct 2004 09:42:27 +0000 (09:42 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@445 48e7efb5-ca39-0410-a469-dd3cf9ba447f

14 files changed:
ChangeLog
configure.ac
include/xbt/dynar.h
src/gras/DataDesc/cbps.c
src/gras/DataDesc/ddt_exchange.c
src/xbt/config.c
src/xbt/dict_cursor.c
src/xbt/dict_elm.c
src/xbt/dynar.c
src/xbt/set.c
testsuite/Makefile.am
testsuite/run_tests.in
testsuite/xbt/dict_crash.c
testsuite/xbt/dynar_int.c

index 6f255aa..d4334a0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-11-07 Martin Quinson
+  - Speed up dynar lookup operation a bit.
+  
+    gras_dynar_get is dead. 
+    
+    Now, you can choose between gras_dynar_get_cpy (the old gras_dynar_get
+    but should be avoided for efficiency reasons) and gras_dynar_get_ptr
+    (which gives you the address of the stored data).
+    
+    gras_dynar_get_as is an helpful macro which allows you to retrieve a
+    copy of the data using an affectation to do the job and not a memcpy.
+    
+    int toto = gras_dynar_get_as(dyn,0,int); rewrites itself to
+    int toto = *(int*)gras_dynar_get_ptr(dyn,0);
+    
+    It does not really speedup the dynar test because they are
+    setting elements all the time (and look them seldom). But the dict does
+    far more lookup than setting.
+
+    So, this brings the dict_crash test from ~33s to ~25s (200000 elms).
+
 2004-11-04 Martin Quinson
   - Allow to (en/dis)able the cycle detection at run time.
   
index 88c7d2b..5a2c0a9 100644 (file)
@@ -3,7 +3,7 @@ AC_PREREQ(2.59)
 #We need a recent ACI
 ACI_PREREQ(2003.01.16)
 
-AC_INIT([GRAS],[0.6.3],[martin.quinson@ens-lyon.fr])
+AC_INIT([GRAS],[0.7],[martin.quinson@ens-lyon.fr])
 AC_CONFIG_SRCDIR([include/gras.h])
 AC_CONFIG_HEADERS([src/gras_config.h])
 
index 9b71233..ff1085d 100644 (file)
@@ -27,7 +27,12 @@ void          gras_dynar_reset(gras_dynar_t *dynar);
 
 
 /* regular array functions */
-void gras_dynar_get(const gras_dynar_t *dynar, int idx, void *const dst);
+void gras_dynar_get_cpy(const gras_dynar_t *dynar, int idx, void *const dst);
+void *gras_dynar_get_ptr(const gras_dynar_t * const dynar,
+                        const int                  idx);
+
+#define gras_dynar_get_as(dynar,idx,type) *(type*)gras_dynar_get_ptr(dynar,idx)
+  
 void gras_dynar_set(gras_dynar_t *dynar, int  idx, const void *src);
 void gras_dynar_remplace(gras_dynar_t *dynar,
                         int idx, const void *object);
index 066fef5..a36c2eb 100644 (file)
@@ -149,7 +149,7 @@ gras_cbps_v_pop (gras_cbps_t        *ps,
     while (l--) {
       char *_name = NULL;
                                                                                 
-      gras_dynar_get(frame, l, &_name);
+      _name = gras_dynar_get_as(frame, l, char*);
       if (!strcmp(name, _name)) {
        gras_dynar_remove_at(frame, l, &_name);
        gras_free(_name);
index 4bd36ed..f132161 100644 (file)
@@ -228,7 +228,7 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1,
     }
     gras_dynar_foreach(d1->category.struct_data.fields, cpt, field1) {
       
-      gras_dynar_get(d2->category.struct_data.fields, cpt, &field2);
+      field2 = gras_dynar_get_as(d2->category.struct_data.fields, cpt, gras_dd_cat_field_t *);
       field_desc_1 = field1->type;
       field_desc_2 = field2->type;
       ret = gras_datadesc_type_cmp(field_desc_1,field_desc_2);
@@ -254,7 +254,7 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1,
     
     gras_dynar_foreach(d1->category.union_data.fields, cpt, field1) {
       
-      gras_dynar_get(d2->category.union_data.fields, cpt, field2);
+      field2 = gras_dynar_get_as(d2->category.union_data.fields, cpt, gras_dd_cat_field_t *);
       field_desc_1 = field1->type;
       field_desc_2 = field2->type;
       ret = gras_datadesc_type_cmp(field_desc_1,field_desc_2);
@@ -387,7 +387,7 @@ gras_datadesc_send_rec(gras_socket_t        *sock,
     TRY(gras_dd_send_int(sock, field_num));
     
     /* Send the content */
-    gras_dynar_get(union_data.fields, field_num, field);
+    field = gras_dynar_get_as(union_data.fields, field_num, gras_dd_cat_field_t *);
     sub_type = field->type;
     
     if (field->pre)
@@ -606,7 +606,7 @@ gras_datadesc_recv_rec(gras_socket_t        *sock,
             type->name, field_num, gras_dynar_length(union_data.fields));
     
     /* Recv the content */
-    gras_dynar_get(union_data.fields, field_num, field);
+    field = gras_dynar_get_as(union_data.fields, field_num, gras_dd_cat_field_t *);
     sub_type = field->type;
     
     TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type,
index 640528e..81cddbe 100644 (file)
@@ -122,7 +122,7 @@ gras_cfg_dump(const char *name,const char *indent,gras_cfg_t *cfg) {
   int ival;
   char *sval;
   double dval;
-  gras_host_t hval;
+  gras_host_t *hval;
 
   if (name)
     printf("%s>> Dumping of the config set '%s':\n",indent,name);
@@ -139,29 +139,29 @@ gras_cfg_dump(const char *name,const char *indent,gras_cfg_t *cfg) {
        
     case gras_cfgelm_int:
       for (i=0; i<size; i++) {
-       gras_dynar_get(cell->content,i,&ival);
+       ival = gras_dynar_get_as(cell->content,i,int);
        printf ("%s    %d\n",indent,ival);
       }
       break;
 
     case gras_cfgelm_double:
       for (i=0; i<size; i++) {
-       gras_dynar_get(cell->content,i,&dval);
+       dval = gras_dynar_get_as(cell->content,i,double);
        printf ("%s    %f\n",indent,dval);
       }
       break;
 
     case gras_cfgelm_string:
       for (i=0; i<size; i++) {
-       gras_dynar_get(cell->content,i,&sval);
+       sval = gras_dynar_get_as(cell->content,i,char*);
        printf ("%s    %s\n",indent,sval);
       }
       break;
 
     case gras_cfgelm_host:
       for (i=0; i<size; i++) {
-       gras_dynar_get(cell->content,i,&hval);
-       printf ("%s    %s:%d\n",indent,hval.name,hval.port);
+       hval = gras_dynar_get_as(cell->content,i,gras_host_t*);
+       printf ("%s    %s:%d\n",indent,hval->name,hval->port);
       }
       break;
 
@@ -967,7 +967,7 @@ gras_cfg_get_int   (gras_cfg_t  *cfg,
             name, gras_dynar_length(cell->content));
   }
 
-  gras_dynar_get(cell->content, 0, (void*)val);
+  *val = gras_dynar_get_as(cell->content, 0, int);
   return no_error;
 }
 
@@ -998,7 +998,7 @@ gras_cfg_get_double(gras_cfg_t *cfg,
             name, gras_dynar_length(cell->content));
   }
 
-  gras_dynar_get(cell->content, 0, (void*)val);
+  *val = gras_dynar_get_as(cell->content, 0, double);
   return no_error;
 }
 
@@ -1031,7 +1031,7 @@ gras_error_t gras_cfg_get_string(gras_cfg_t *cfg,
             name, gras_dynar_length(cell->content));
   }
 
-  gras_dynar_get(cell->content, 0, (void*)val);
+  *val = gras_dynar_get_as(cell->content, 0, char *);
   return no_error;
 }
 
@@ -1065,7 +1065,7 @@ gras_error_t gras_cfg_get_host  (gras_cfg_t *cfg,
             name, gras_dynar_length(cell->content));
   }
 
-  gras_dynar_get(cell->content, 0, (void*)val);
+  val = gras_dynar_get_as(cell->content, 0, gras_host_t*);
   *host=val->name;
   *port=val->port;
   
index 5e9269e..a4308fb 100644 (file)
@@ -206,8 +206,8 @@ gras_dict_cursor_get_or_free(gras_dict_cursor_t **cursor,
     return FALSE;
   }
     
-  gras_dynar_get((*cursor)->keys,     (*cursor)->pos,     key    );
-  gras_dynar_get((*cursor)->key_lens, (*cursor)->pos_len, &key_len);
+  *key    = gras_dynar_get_as((*cursor)->keys,     (*cursor)->pos,     char*);
+  key_len = gras_dynar_get_as((*cursor)->key_lens, (*cursor)->pos_len, int);
 
   errcode = gras_dictelm_get_ext((*cursor)->head, *key, key_len, data);
   if (errcode == mismatch_error) {
@@ -238,7 +238,7 @@ gras_dict_cursor_get_key(gras_dict_cursor_t  *p_cursor,
 
   TRY(__cursor_not_null(p_cursor));
 
-  gras_dynar_get(p_cursor->keys, p_cursor->pos - 1, key);
+  *key = gras_dynar_get_as(p_cursor->keys, p_cursor->pos - 1, char*);
 
   return errcode;
 }
@@ -258,8 +258,8 @@ gras_dict_cursor_get_data(gras_dict_cursor_t  *p_cursor,
 
   TRY(__cursor_not_null(p_cursor));
 
-  gras_dynar_get(p_cursor->keys,     p_cursor->pos-1,     &key    );
-  gras_dynar_get(p_cursor->key_lens, p_cursor->pos_len-1, &key_len);
+  key     = gras_dynar_get_as(p_cursor->keys,     p_cursor->pos-1,  char *);
+  key_len = gras_dynar_get_as(p_cursor->key_lens, p_cursor->pos_len-1, int);
 
   TRY(gras_dictelm_get_ext(p_cursor->head, key, key_len, data));
 
index 380a355..0ee32ad 100644 (file)
@@ -270,7 +270,7 @@ _dict_child_cmp(gras_dictelm_t *p_dict,
   int           o       = *p_offset;
   int           m       = *p_match;
 
-  gras_dynar_get(p_dict->sub, pos, &p_child);
+  p_child = gras_dynar_get_as(p_dict->sub, pos, gras_dictelm_t*);
 
   /* Compute the length of the prefix
      and if the searched key is before or after cur */
@@ -458,7 +458,7 @@ _gras_dictelm_set_rec(gras_dictelm_t     *p_head,
     {
       gras_dictelm_t *p_child = NULL;
 
-      gras_dynar_get(p_head->sub, pos, &p_child);
+      p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
       CDEBUG1(dict_add, "-> Change the value of the child %p", (void*)p_child);
       _gras_dictelm_change_value(p_child, data, free_ctn);
 
@@ -471,7 +471,7 @@ _gras_dictelm_set_rec(gras_dictelm_t     *p_head,
     {
       gras_dictelm_t *p_child = NULL;
 
-      gras_dynar_get(p_head->sub, pos, &p_child);
+      p_child=gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
       CDEBUG2(dict_add,"-> Recurse on %p (offset=%d)", (void*)p_child, offset);
 
       _gras_dictelm_set_rec(p_child, key, key_len, 
@@ -484,7 +484,7 @@ _gras_dictelm_set_rec(gras_dictelm_t     *p_head,
       gras_dictelm_t *p_new   = NULL;
       gras_dictelm_t *p_child = NULL;
 
-      gras_dynar_get(p_head->sub, pos, &p_child);
+      p_child=gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
       _gras_dictelm_alloc(key, key_len, old_offset, data, free_ctn, &p_new);
 
       CDEBUG2(dict_add, "-> The child %p become child of new dict (%p)",
@@ -506,7 +506,7 @@ _gras_dictelm_set_rec(gras_dictelm_t     *p_head,
       int          anc_key_len = offset;
 
       _gras_dictelm_alloc(key, key_len, offset, data, free_ctn, &p_new);
-      gras_dynar_get(p_head->sub, pos, &p_child);
+      p_child=gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
 
       anc_key = gras_memdup(key, anc_key_len);
 
@@ -646,7 +646,7 @@ _gras_dictelm_get_rec(gras_dictelm_t *p_head,
       {
         gras_dictelm_t *p_child = NULL;
 
-        gras_dynar_get(p_head->sub, pos, &p_child);
+        p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
         *data = p_child->content;
 
         return no_error;
@@ -656,7 +656,7 @@ _gras_dictelm_get_rec(gras_dictelm_t *p_head,
       {
         gras_dictelm_t *p_child = NULL;
 
-        gras_dynar_get(p_head->sub, pos, &p_child);
+        p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
 
         return _gras_dictelm_get_rec(p_child, key, key_len, offset, data);
       }
@@ -726,7 +726,7 @@ _collapse_if_need(gras_dictelm_t *p_head,
 
   if (pos >= 0) {
     /* Remove the child if |it's key| == 0 (meaning it's dead) */
-    gras_dynar_get(p_head->sub, pos, &p_child);
+    p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
 
     if (offset >= p_child->key_len) {
 
@@ -749,7 +749,7 @@ _collapse_if_need(gras_dictelm_t *p_head,
     return; /* cannot collapse */
   }
 
-  gras_dynar_get(p_head->sub, 0, &p_child);
+  p_child = gras_dynar_get_as(p_head->sub, 0, gras_dictelm_t*);
 
   /* Get the child's key as new key */
   CDEBUG2(dict_collapse,
@@ -820,7 +820,7 @@ _gras_dictelm_remove_rec(gras_dictelm_t *p_head,
       {
         gras_dictelm_t *p_child = NULL;
 
-        gras_dynar_get(p_head->sub, pos, &p_child);
+        p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
         /*DEBUG5("Recurse on child %d of %p to remove %.*s (prefix=%d)",
           pos, (void*)p_child, key+offset, key_len-offset,offset);*/
         TRY(_gras_dictelm_remove_rec(p_child, key, key_len, offset));
index ad9b0f3..ca57b58 100644 (file)
@@ -90,7 +90,7 @@ _gras_dynar_expand(gras_dynar_t * const dynar,
 static _GRAS_INLINE
 void *
 _gras_dynar_elm(const gras_dynar_t * const dynar,
-                const unsigned long               idx) {
+                  const unsigned long        idx) {
   char * const data    = dynar->data;
   const unsigned long elmsize = dynar->elmsize;
 
@@ -217,6 +217,26 @@ gras_dynar_length(const gras_dynar_t * const dynar) {
   return (dynar ? (unsigned long) dynar->used : (unsigned long)0);
 }
 
+/**
+ * gras_dynar_get_cpy:
+ * @dynar: information dealer
+ * @idx: index of the slot we want to retrive
+ * @dst: where to pu the result to.
+ *
+ * Retrieve a copy of the Nth element of a dynar.
+ */
+void
+gras_dynar_get_cpy(const gras_dynar_t * const dynar,
+                  const int                  idx,
+                  void               * const dst) {
+
+  __sanity_check_dynar(dynar);
+  __sanity_check_idx(idx);
+  __check_inbound_idx(dynar, idx);
+
+  _gras_dynar_get_elm(dst, dynar, idx);
+}
+
 /**
  * gras_dynar_get:
  * @dynar: information dealer
@@ -226,16 +246,15 @@ gras_dynar_length(const gras_dynar_t * const dynar) {
  * Retrieve the Nth element of a dynar. Warning, the returned value is the actual content of 
  * the dynar. Make a copy before fooling with it.
  */
-void
-gras_dynar_get(const gras_dynar_t * const dynar,
-               const int                  idx,
-               void               * const dst) {
+void*
+gras_dynar_get_ptr(const gras_dynar_t * const dynar,
+                  const int                  idx) {
 
   __sanity_check_dynar(dynar);
   __sanity_check_idx(idx);
   __check_inbound_idx(dynar, idx);
 
-  _gras_dynar_get_elm(dst, dynar, idx);
+  return _gras_dynar_elm(dynar, idx);
 }
 
 /**
index aa42896..ff05014 100644 (file)
@@ -156,7 +156,7 @@ gras_error_t gras_set_get_by_id      (gras_set_t     *set,
 
   /* Don't bother checking the bounds, the dynar does so */
 
-  gras_dynar_get(set->dynar,id,dst);
+  *dst = gras_dynar_get_as(set->dynar,id,gras_set_elm_t *);
   DEBUG3("Lookup type of id %d (of %lu): %s", 
         id, gras_dynar_length(set->dynar), (*dst)->name);
   
index 6da5a7f..90819a0 100644 (file)
@@ -6,6 +6,7 @@ DISTCLEANFILES =  gras/.libs/* xbt/.libs/*
 MAINTAINERCLEANFILES=Makefile.in
 EXTRA_DIST=run_tests.in \
   gras/datadesc.little32 gras/datadesc.little64 gras/datadesc.big32 gras/datadesc.big64 \
+  gras/datadesc.aix \
   gras/mk_datadesc_structs.pl
 
 # Test stuff
index 2cbcb50..8795b91 100755 (executable)
@@ -17,12 +17,12 @@ for test in xbt/log_usage                                          \
            xbt/config_usage                                       \
            \
            gras/trp_tcp_usage      gras/trp_file_usage             \
-           gras/datadesc_usage                                     
-#          "gras/datadesc_usage --read @srcdir@/datadesc.little32" \
-#          "gras/datadesc_usage --read @srcdir@/datadesc.big32"    \
-#          "gras/datadesc_usage --read @srcdir@/datadesc.big64" 
-
-#          "gras/datadesc_usage --read @srcdir@/datadesc.little64" \
+           gras/datadesc_usage                                     \
+           "gras/datadesc_usage --read @srcdir@/gras/datadesc.little32" \
+           "gras/datadesc_usage --read @srcdir@/gras/datadesc.little64" \
+           "gras/datadesc_usage --read @srcdir@/gras/datadesc.big32"    \
+           "gras/datadesc_usage --read @srcdir@/gras/datadesc.big64"    \
+           "gras/datadesc_usage --read @srcdir@/gras/datadesc.aix"
 do                 
   tests_nb=`expr $tests_nb + 1`
   echo "#### Test $test"
index d97aaf4..8c4b79b 100644 (file)
@@ -13,7 +13,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#define NB_ELM 20000
+#define NB_ELM 200000
 #define SIZEOFKEY 1024
 
 static void print_str(void *str);
index c01aeac..4226d5a 100644 (file)
@@ -18,6 +18,7 @@ int main(int argc,char *argv[]) {
    gras_dynar_t *d;
    gras_error_t errcode;
    int i,cpt,cursor;
+   int *iptr;
    
    gras_init_defaultlog(&argc,argv,"dynar.thresh=debug");
 
@@ -36,8 +37,8 @@ int main(int argc,char *argv[]) {
      DEBUG2("Push %d, length=%lu",cpt, gras_dynar_length(d));
    }
    for (cursor=0; cursor< NB_ELEM; cursor++) {
-     gras_dynar_get(d,cursor,&cpt);
-     gras_assert2(cursor == cpt,
+     iptr=gras_dynar_get_ptr(d,cursor);
+     gras_assert2(cursor == *iptr,
                  "The retrieved value is not the same than the injected one (%d!=%d)",
                  cursor,cpt);
    }