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