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
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users