LAM/MPI logo

Performance Issues with LAM on Linux 2.2.x

  |   Home   |   Download   |   Documentation   |   FAQ   |  

sox.cc

#include <errno.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/uio.h> #include <netinet/in.h> #include <netdb.h> #include <fcntl.h> #include <string.h> #include "mrw.h" static const int MAXCOUNT = (1048576 * 8); static const int NUMTESTS = 50; static const int IGNORE = 10; static const int SHORTTCPMSG = 32768; typedef unsigned long long int pptimer_t; #ifdef __GNUC__ __inline__ #endif pptimer_t rdtsc(); int sox_listen(int); int sox_connect(char *remotehost, unsigned short port); int sox_write(int s, char* message, int n); int sox_read(int s, char* message, int n); int mreadv(int,struct iovec*,int); int mwritev(int,struct iovec*,int); int main(int argc, char* argv[]) { int s; int pn; char *message; char myhostname[1024]; int count; pptimer_t total, timer_begin, timer_end, timer_diff, avg; pptimer_t *avgs; int rank; int i,j; if (argc < 4) { printf("usage: %s <rank> <hostname> <port>\n",argv[0]); exit(1); } message = (char*) malloc(MAXCOUNT * sizeof(char)); avgs = (pptimer_t*) malloc (24 * sizeof(pptimer_t)); pn = atoi(argv[3]); strcpy(myhostname,argv[2]); rank = atoi(argv[1]); if (atoi(argv[1]) == 1) { sleep(3); s = sox_connect(myhostname,pn); } else { s = sox_listen(pn); } fprintf(stderr,"Connection established\n"); if (rank == 1) { for (count = 1; count <= MAXCOUNT; count*=2) { for (i = 0; i < NUMTESTS; i++) { sox_read(s,message,count); sox_write(s,message,count); } } } else { for (count = 1, j = 0; count <= MAXCOUNT; count*=2, j++) { fprintf(stderr,"%10d",count); total = 0; for (i = 0; i < NUMTESTS; i++) { fprintf(stderr,"."); timer_begin = rdtsc(); sox_write(s, message, count); sox_read(s, message, count); timer_end = rdtsc(); timer_diff = timer_end - timer_begin; if (i > IGNORE) total += timer_diff; } fprintf(stderr,"\n"); avg = total / (NUMTESTS - IGNORE); avgs[j] = avg; } printf("x = [ "); for (count = 1; count <= MAXCOUNT; count*=2) printf("%d ",count); printf("]; \ncycles = [ "); for (i = 0; i < j; i++) { #ifdef __GNUC__ printf("%Ld ",avgs[i]); #else printf("%lld ",avgs[i]); #endif } printf("];\n"); printf("loglog(x,cycles,'x-');\n"); } return 0; } int sox_read(int s, char* message, int n) { int total_bytes_read=0; int bytes_read=0; int m; #ifdef USE_WRITEV_ int nread; int savelen; char *savebase; int numbufs = n / SHORTTCPMSG + 1; struct iovec myovec[257]; // Hard coded for max of 8MB int i; for (i = 0; i < numbufs; i++) { myovec[i].iov_base = message + i; if (i < numbufs-1) myovec[i].iov_len = SHORTTCPMSG; else myovec[i].iov_len = n - (numbufs-1) * SHORTTCPMSG; } total_bytes_read = mreadv(s,myovec,numbufs); #else for (m = (n > SHORTTCPMSG) ? SHORTTCPMSG : n; n > 0; n-=SHORTTCPMSG, m = (n > SHORTTCPMSG) ? SHORTTCPMSG : n) { bytes_read = 0; while (bytes_read < m) { bytes_read += read(s,message + bytes_read,m-bytes_read); } total_bytes_read += bytes_read; } #endif return total_bytes_read; } int sox_write(int s, char* message, int n) { int total_bytes_written=0; int bytes_written=0; int m; #ifdef USE_WRITEV_ struct iovec myovec[257]; // Hard coded for max of 8MB int numbufs = n / SHORTTCPMSG + 1; int i; int nwritten; int savelen; char* savebase; for (i = 0; i < numbufs; i++) { myovec[i].iov_base = message + i; if (i < numbufs-1) myovec[i].iov_len = SHORTTCPMSG; else myovec[i].iov_len = n - (numbufs-1) * SHORTTCPMSG; } total_bytes_written = mwritev(s,myovec,numbufs); #else for (m = (n > SHORTTCPMSG) ? SHORTTCPMSG : n; n > 0; n-=SHORTTCPMSG, m = (n > SHORTTCPMSG) ? SHORTTCPMSG : n){ bytes_written=0; while (bytes_written < m) { bytes_written += write(s,message+bytes_written,m-bytes_written); } total_bytes_written+=bytes_written; } #endif return total_bytes_written; } int sox_listen(int portfoo) { int s; int p; char host[1024]; struct hostent *hp, *ihp; struct sockaddr_in sin, incoming; int port; int i, result; unsigned int len; port = portfoo; /* get my host name and fill in hostent struct */ gethostname(host, sizeof host); hp = gethostbyname(host); if ( hp == NULL ) exit(1); s = socket(AF_INET, SOCK_STREAM, 0); if ( s < 0 ) { perror("socket:"); exit(s); } /* set up the address and port */ sin.sin_family = AF_INET; sin.sin_port = htons(port); memcpy(&sin.sin_addr, hp->h_addr_list[0], hp->h_length); /* bind socket s to address sin */ result = bind(s, (struct sockaddr *)&sin, sizeof(sin)); if ( result < 0 ) { perror("bind:"); exit(result); } /* listen to the network for connections */ result = listen(s, 2); if ( result < 0 ) { perror("listen:"); exit(result); } len = sizeof(struct sockaddr_in); /* wait to accept a connection */ p = accept(s, (struct sockaddr *) &incoming, &len); if ( p < 0 ) { perror("accept:"); exit(result); } ihp = gethostbyaddr((char *)&incoming.sin_addr, sizeof(struct in_addr), AF_INET); return p; } int sox_connect(char *remotehost, unsigned short port) { struct sockaddr_in sa; struct hostent *hp; int s; if ((hp=gethostbyname(remotehost)) == NULL) { /* DNS lookup */ printf("host lookup failure\n"); return -1; } memset(&sa,0,sizeof(sa)); memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); sa.sin_family=hp->h_addrtype; sa.sin_port=htons((u_short)port); if ((s = socket(hp->h_addrtype,SOCK_STREAM,IPPROTO_IP)) < 0) { perror("sox_connect"); return -1; } if(connect(s,(struct sockaddr *)&sa,sizeof sa) < 0) { close(s); perror("sox_connect"); return -1; } return s; } #ifdef __GNUC__ __inline__ #endif pptimer_t rdtsc() { pptimer_t x; #ifdef __GNUC__ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); #else x = gethrtime(); #endif return x; }