[openib-general] [PATCH] libmthca: optimize calls to htonl with constant parameter

Michael S. Tsirkin mst at mellanox.co.il
Fri Feb 23 03:24:15 PST 2007


> So what is different in your setup that causes this patch to make a
> difference for you?

Hmm. I agree it is somewhat strange.

Below is a simple test that attempts to compare htonl, CONSTANT_HTONL,
and an array-driven implementation. The code line is taken directly from htonl.
Could you compile and run it please?

I see:

$ gcc -O2 1.c
$ ./a.out
test1
122396.00 usec
test2
10517799.00 usec
test3
104099.00 usec

which seems to imply CONSTANT_HTONL is much faster.

Ideas?

-------------------------------


#include <stdio.h>
#include <sys/time.h>
#include <time.h>

#include <endian.h>

#define SIZE 255

enum ibv_send_flags {
        IBV_SEND_FENCE          = 1 << 0,
        IBV_SEND_SIGNALED       = 1 << 1,
        IBV_SEND_SOLICITED      = 1 << 2,
        IBV_SEND_INLINE         = 1 << 3
};

enum {
        MTHCA_NEXT_DBD       = 1 << 7,
        MTHCA_NEXT_FENCE     = 1 << 6,
        MTHCA_NEXT_CQ_UPDATE = 1 << 3,
        MTHCA_NEXT_EVENT_GEN = 1 << 2,
        MTHCA_NEXT_SOLICIT   = 1 << 1,
};

int ar[SIZE];


void init_ar()
{
	ar[0]=htonl(1);
	ar[IBV_SEND_SIGNALED]=htonl(MTHCA_NEXT_CQ_UPDATE|1);;
	ar[IBV_SEND_SOLICITED]=htonl(MTHCA_NEXT_SOLICIT|1);;
	ar[IBV_SEND_SIGNALED|IBV_SEND_SOLICITED]=htonl(MTHCA_NEXT_CQ_UPDATE|MTHCA_NEXT_SOLICIT|1);;
}


int test1(int x) 
{
	return ar[x & (IBV_SEND_SIGNALED | IBV_SEND_SOLICITED)];
}


int test2(int x) 
{
	return 
		((x & IBV_SEND_SIGNALED)  ? htonl(MTHCA_NEXT_CQ_UPDATE) : 0) |
		((x & IBV_SEND_SOLICITED)  ? htonl(MTHCA_NEXT_SOLICIT) : 0) |
		htonl(1);
}

#if __BYTE_ORDER == __LITTLE_ENDIAN
#define CONSTANT_HTONL(x) \
	((x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24))
#elif __BYTE_ORDER == __BIG_ENDIAN
#define CONSTANT_HTONL(x) (x)
#else
#define CONSTANT_HTONL(x) htonl(x)
#endif

int test3(int x) 
{
	return 
		((x & IBV_SEND_SIGNALED)  ? CONSTANT_HTONL(MTHCA_NEXT_CQ_UPDATE) : 0) |
		((x & IBV_SEND_SOLICITED) ? CONSTANT_HTONL(MTHCA_NEXT_SOLICIT) : 0) |
		CONSTANT_HTONL(1);
}

struct timeval           start, end;

void timestart(void)
{
	if (gettimeofday(&start, NULL)) {
		perror("gettimeofday");
		return;
	}

}


void timeend(void)
{
	if (gettimeofday(&end, NULL)) {
		perror("gettimeofday");
		return;
	}

	{
		float usec = (end.tv_sec - start.tv_sec) * 1000000 +
			(end.tv_usec - start.tv_usec);

		printf("%.2f usec\n", usec);
	}

}

main() 
{
	int i;

	init_ar();

	printf("test1\n");

	timestart();

	for (i=0; i<100000000; ++i) {
		(void) test1(IBV_SEND_SIGNALED);
		(void) test1(0);
		(void) test1(IBV_SEND_SIGNALED | IBV_SEND_SOLICITED);
		(void) test1(IBV_SEND_SOLICITED);
	}
	timeend();

	printf("test2\n");
	timestart();

	for (i=0; i<100000000; ++i) {
		(void) test2(IBV_SEND_SIGNALED);
		(void) test2(0);
		(void) test2(IBV_SEND_SIGNALED | IBV_SEND_SOLICITED);
		(void) test2(IBV_SEND_SOLICITED);
	}
	timeend();
	printf("test3\n");
	timestart();

	for (i=0; i<100000000; ++i) {
		(void) test3(IBV_SEND_SIGNALED);
		(void) test3(0);
		(void) test3(IBV_SEND_SIGNALED | IBV_SEND_SOLICITED);
		(void) test3(IBV_SEND_SOLICITED);
	}
	timeend();
}

-- 
MST




More information about the general mailing list