Revision: 486
          http://vde.svn.sourceforge.net/vde/?rev=486&view=rev
Author:   rd235
Date:     2011-04-04 09:03:07 +0000 (Mon, 04 Apr 2011)

Log Message:
-----------
experimental branch: performance optimization on hash: uint64 key (instead of 
char *), 64bit comparison is faster than memcmp.

Modified Paths:
--------------
    branches/rd235/vde-2/src/vde_switch/hash.c

Modified: branches/rd235/vde-2/src/vde_switch/hash.c
===================================================================
--- branches/rd235/vde-2/src/vde_switch/hash.c  2011-03-28 14:56:29 UTC (rev 
485)
+++ branches/rd235/vde-2/src/vde_switch/hash.c  2011-04-04 09:03:07 UTC (rev 
486)
@@ -46,39 +46,41 @@
        struct hash_entry **prev;
        time_t last_seen;
        int port;
-       unsigned char dst[ETH_ALEN+2];
+       u_int64_t dst;
 };
 
 static struct hash_entry **h;
 
-static int calc_hash(unsigned char *src)
+static int calc_hash(u_int64_t src)
 {
-       register int x= (*(u_int32_t *) &src[0]);
-       register int y= (*(u_int32_t *) &src[4]);
-       x = x * 0x03050709 + y * 0x0b0d1113;
+       register int x = src * 0x030507090b0d1113LL;
        x = (x ^ x >> 12 ^ x >> 8 ^ x >> 4) & hash_mask;
        /*printf("HASH %02x:%02x:%02x:%02x:%02x:%02x V%d -> %d\n", src[0], 
src[1], src[2], src[3], src[4], src[5],(src[6]>>8)+src[7],x);*/
        return x; 
 }
 
+#define EMAC2MAC6(X) \
+       (u_int)((X)&0xff), (u_int)(((X)>>8)&0xff), (u_int)(((X)>>16)&0xff), \
+       (u_int)(((X)>>24)&0xff), (u_int)(((X)>>32)&0xff), 
(u_int)(((X)>>40)&0xff)
+#define EMAC2VLAN(X) ((u_int16_t) ((X)>>48))
+#define EMAC2VLAN2(X) ((u_int) (((X)>>48) &0xff)), ((u_int) (((X)>>56) &0xff))
+
 #define find_entry(MAC) \
        ({struct hash_entry *e; \
         int k = calc_hash(MAC);\
-        for(e = h[k]; e && memcmp(&e->dst, (MAC), ETH_ALEN+2); e = e->next)\
+        for(e = h[k]; e && e->dst != (MAC); e = e->next)\
         ;\
         e; })
 
-#define extmac(EMAC,MAC,VLAN) \
-       ({ memcpy(EMAC,(MAC),ETH_ALEN); \
-          *((u_int16_t *)(EMAC+ETH_ALEN))=(u_int16_t) VLAN; \
-          EMAC; })
 
+#define extmac(MAC,VLAN) \
+           ((*(u_int32_t *) &((MAC)[0])) + ((u_int64_t) ((*(u_int16_t *) 
&((MAC)[4]))+ ((u_int64_t) (VLAN) << 16)) << 32))
+
 /* looks in global hash table 'h' for given address, and return associated
  * port */
 int find_in_hash(unsigned char *dst,int vlan)
 {
-       unsigned char edst[ETH_ALEN+2];
-       struct hash_entry *e = find_entry(extmac(edst,dst,vlan));
+       struct hash_entry *e = find_entry(extmac(dst,vlan));
        if(e == NULL) return -1;
        return(e->port);
 }
@@ -86,12 +88,12 @@
 
 int find_in_hash_update(unsigned char *src,int vlan,int port)
 {
-       unsigned char esrc[ETH_ALEN+2];
        struct hash_entry *e;
-       int k = calc_hash(extmac(esrc,src,vlan));
+       u_int64_t esrc=extmac(src,vlan);
+       int k = calc_hash(esrc);
        int oldport;
        time_t now;
-       for(e = h[k]; e && memcmp(&e->dst, esrc, ETH_ALEN+2); e = e->next)
+       for(e = h[k]; e && e->dst != esrc; e = e->next)
                ;
        if(e == NULL) {
                e = (struct hash_entry *) malloc(sizeof(*e));
@@ -101,9 +103,9 @@
                }
 
                DBGOUT(DBGHASHNEW,"%02x:%02x:%02x:%02x:%02x:%02x VLAN %02x:%02x 
Port %d",
-                                    esrc[0], esrc[1], esrc[2], esrc[3], 
esrc[4], esrc[5], esrc[6], esrc[7], port);
+                               EMAC2MAC6(esrc), EMAC2VLAN2(esrc), port);
                EVENTOUT(DBGHASHNEW,esrc);
-               memcpy(&e->dst, esrc, ETH_ALEN+2);
+               e->dst = esrc;
                if(h[k] != NULL) h[k]->prev = &(e->next);
                e->next = h[k];
                e->prev = &(h[k]);
@@ -125,7 +127,7 @@
 
 #define delete_hash_entry(OLD) \
        ({ \
-        DBGOUT(DBGHASHDEL,"%02x:%02x:%02x:%02x:%02x:%02x VLAN %02x:%02x Port 
%d", OLD->dst[0], OLD->dst[1], OLD->dst[2], OLD->dst[3], OLD->dst[4], 
OLD->dst[5], OLD->dst[6], OLD->dst[7], OLD->port);\
+        DBGOUT(DBGHASHDEL,"%02x:%02x:%02x:%02x:%02x:%02x VLAN %02x:%02x Port 
%d", EMAC2MAC6(OLD->dst), EMAC2VLAN2(OLD->dst), OLD->port); \
         EVENTOUT(DBGHASHDEL,OLD->dst);\
         *((OLD)->prev)=(OLD)->next; \
         if((OLD)->next != NULL) (OLD)->next->prev = (OLD)->prev; \
@@ -135,8 +137,7 @@
 
 void delete_hash(unsigned char *dst,int vlan)
 {
-       unsigned char edst[ETH_ALEN+2];
-       struct hash_entry *old = find_entry(extmac(edst,dst,vlan));
+       struct hash_entry *old = find_entry(extmac(dst,vlan));
 
        if(old == NULL) return;
        qtime_csenter();
@@ -176,7 +177,7 @@
 static void delete_vlan_iterator (struct hash_entry *e, void *arg)
 {
        int *vlan=(int *)arg;
-       if (*((u_int16_t *)(e->dst+ETH_ALEN)) == (u_int16_t)(*vlan))
+       if (EMAC2VLAN(e->dst) == (u_int16_t)(*vlan))
                delete_hash_entry(e);
 }
 
@@ -192,7 +193,7 @@
 static void delete_vlanport_iterator (struct hash_entry *e, void *arg)
 {
        struct vlanport *vp=(struct vlanport *)arg;
-       if (*((u_int16_t *)(e->dst+ETH_ALEN)) == (u_int16_t)(vp->vlan) &&
+       if ((EMAC2VLAN(e->dst)) == (u_int16_t)(vp->vlan) &&
                        e->port == vp->port)
                delete_hash_entry(e);
 }
@@ -210,7 +211,7 @@
 static void delete_vlansetofports_iterator (struct hash_entry *e, void *arg)
 {
        struct vlansetofports *vp=(struct vlansetofports *)arg;
-       if (*((u_int16_t *)(e->dst+ETH_ALEN)) == (u_int16_t)(vp->vlan) &&
+       if ((EMAC2VLAN(e->dst)) == (u_int16_t)(vp->vlan) &&
                        ba_check(vp->setofports,e->port))
                delete_hash_entry(e);
 }
@@ -329,8 +330,8 @@
 static int find_hash(FILE *fd,char *strmac)
 {
        int maci[ETH_ALEN];
-       unsigned char mac[ETH_ALEN];
-       unsigned char emac[ETH_ALEN+2];
+       unsigned char macv[ETH_ALEN];
+       unsigned char *mac=macv;
        int rv=-1;
        int vlan=0;
        struct hash_entry *e;
@@ -344,14 +345,13 @@
                register int i;
                for (i=0;i<ETH_ALEN;i++)
                        mac[i]=maci[i];
-               e=find_entry(extmac(emac,mac,vlan));
+               e=find_entry(extmac(mac,vlan));
                if (e==NULL)
                        return ENODEV;
                else {
                        printoutc(fd,"Hash: %04d Addr: 
%02x:%02x:%02x:%02x:%02x:%02x VLAN %04d to port: %03d  "
                                        "age %ld secs", calc_hash(e->dst),
-                                       e->dst[0], e->dst[1], e->dst[2], 
e->dst[3], e->dst[4], e->dst[5],
-                                       ((e->dst[6]<<8) + e->dst[7]), 
e->port+1, qtime() - e->last_seen);
+                               EMAC2MAC6(e->dst),EMAC2VLAN(e->dst), e->port+1, 
qtime() - e->last_seen);
                        return 0;
                }
        }
@@ -363,9 +363,7 @@
        FILE *pfd=arg;
        printoutc(pfd,"Hash: %04d Addr: %02x:%02x:%02x:%02x:%02x:%02x VLAN %04d 
to port: %03d  " 
                        "age %ld secs", calc_hash(e->dst),
-                       e->dst[0], e->dst[1], e->dst[2], e->dst[3], e->dst[4], 
e->dst[5],
-                       *((u_int16_t *)(e->dst+ETH_ALEN)),
-                       e->port, qtime() - e->last_seen);
+                       EMAC2MAC6(e->dst),EMAC2VLAN(e->dst), e->port, qtime() - 
e->last_seen);
 }
 
 static int print_hash(FILE *fd)


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
vde-users mailing list
vde-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vde-users

Reply via email to