[comp.protocols.nfs] weird NFS speeds

gamiddleton@watmath.waterloo.edu (Guy Middleton) (09/30/89)

I have been testing NFS performance on some workstations, using a program to
write a 20-megabyte file with different-sized buffers.  The speed listed for
a Sparc1 when served by a Mips M/2000 is not a typo.  It really is that
slow.  Anybody have any idea why?

write speeds, in kilobytes/sec

blocksize:		8K	4K	2K	1K

server Mips M/2000:

DECstation 3100		310	135	135
Mips RS2030		310	140	140
Sun Sparc1		9	108	95	145

server Sun 4/280:

DECstation 3100		79	59	53	59
Mips RS2030		85	54	49	40
Sun Sparc1		82	67	62	62

gamiddleton@watmath.waterloo.edu (Guy Middleton) (10/03/89)

In article <29591@watmath.waterloo.edu> gamiddleton@watmath.waterloo.edu (Guy Middleton) writes:
> I have been testing NFS performance on some workstations, using a program to
> write a 20-megabyte file with different-sized buffers.

A couple of people have suggested that I post the program I used.  It's no big
deal.  There is no timing code here, I used csh's "time" function to get
elapsed and CPU times:

#include <stdio.h>
/*
 * some BSD-like systems don't define "BSD" in the preprocessor
 * you may have to do it by hand
 */
#ifdef BSD
#include <sys/file.h>
#else
#include <fcntl.h>
#endif

#define	BLOCK		1024

#define	BUFBLOCKS	8		/* # of BLOCKs per read/write */
#define	FILESIZE	(1024 * 20)	/* size of file in BLOCKs */

#define	WRITE		(O_CREAT|O_RDWR)
#define	READ		O_RDONLY

#define	LINELEN		128

char	filename[] = "xxx";

/*
 * syntax:
	io ["read" | "write"] [blocksize]
 * default is read 8K blocks
 */

main( argc, argv )
	char **argv;
{
	extern char *calloc();
	extern int read(), write();

	int i, ff, iterations;
	unsigned memsize;
	char *mp;

	unsigned bufblocks = BUFBLOCKS;
	int mode = READ;
	int (*func)() = read;


	for (i = 1; i < argc; i++) {
		if (strcmp( argv[i], "write" ) == 0) {
			mode = WRITE;
			continue;
		}
		if (strcmp( argv[i], "read" ) == 0) {
			mode = READ;
			continue;
		}
		bufblocks = atoi( argv[i] );
	}
	
	memsize = bufblocks * BLOCK;

	if (mode == WRITE) {
		func = write;
		printf( "writing" );
	}
	else
		printf( "reading" );

	printf( " with buffer size %d\n", memsize );

	if ((mp = calloc(memsize, (unsigned) 1)) == (char *) NULL) {
		perror("calloc");
		exit(1);
	}

	if ((ff = open(filename, mode, 0666)) < 0) {
		char errmsg[LINELEN];
		sprintf( errmsg, "open %s", filename );
		perror( errmsg );
		exit(1);
	}

	iterations = FILESIZE / bufblocks;

	for (i=0; i<iterations; i++)
		if ((*func)( ff, mp, memsize ) != memsize) {
			perror((func == read) ? "read" : "write");
			exit(1);
		}

	return (0);
}

wje@igate (William J. Earl) (10/07/89)

In article <29591@watmath.waterloo.edu>, gamiddleton@watmath (Guy Middleton) writes:
> I have been testing NFS performance on some workstations, using a program to
> write a 20-megabyte file with different-sized buffers.  The speed listed for
> a Sparc1 when served by a Mips M/2000 is not a typo.  It really is that
> slow.  Anybody have any idea why?
> 
> write speeds, in kilobytes/sec
> 
> blocksize:		8K	4K	2K	1K
> 
> server Mips M/2000:
> 
> DECstation 3100		310	135	135
> Mips RS2030		310	140	140
> Sun Sparc1		9	108	95	145
> 
> server Sun 4/280:
> 
> DECstation 3100		79	59	53	59
> Mips RS2030		85	54	49	40
> Sun Sparc1		82	67	62	62

       You will probably have to look at the network traffic with a
"sniffer" to be certain, but the most likely explanation for the
Sparc1 client-M/2000 server case is that one or the other system
is dropping packets.  NFS performance gets terrible very fast if
someone drops packets.  If there is no other NFS traffic on either
system, look at the output of nfsstat on each.  If the client (Sparc1)
is getting rpc timeouts, then dropped packets is most likely the
problem.  If the server (M/2000) calls count goes up faster than the
client calls count, the client is probably dropping replies; otherwise,
the server is probably dropping requests.

     A sniffer would of course make the situation obvious, since you
would see just which packets were retransmitted.