Measure data transmission rates through unix pipes [followup to my net.unix-wizards article]
Michael W. Herman
mwherman at watcgl.UUCP
Thu May 16 22:46:59 AEST 1985
Don't be concerned about the warning msgs produced by line 34 of
listener.c. For some block sizes ("chunks"), an odd sized block
is transmitted to insure that a full 1M byte of data is transmitted
in the cases where 1M is not an integral multiple of the block size.
The timing statistics are written to *stdout*. *timesPrint* insures
that the talker and listener don't write to *stdout* at the same
time. Error msgs appear on *stderr*. Enjoy.
Michael Herman
Computer Graphics Laboratory
Department of Computer Science
University of Waterloo
Waterloo, Ontario, Canada N2L 3G1
UUCP: {allegra,ihnp4,watmath}!watcgl!mwherman
-or- {cbosgd,clyde,decvax,linus,tektronix,utcsrgv}!watmath!watcgl!mwherman
CSNET: mwherman%watcgl at waterloo.CSNET
ARPA: mwherman%watcgl%waterloo.CSNET at csnet-relay.ARPA
---- Tear here --------------------------------------------------------------
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# Makefile hdr.h listener.c stats.example talker.c timesPrint.c
echo x - Makefile
cat > "Makefile" << '//E*O*F Makefile//'
CFLAGS =
LIBS = timesPrint.o
all: talker listener
talker: talker.c hdr.h timesPrint.o
cc ${CFLAGS} $@.c -o $@ ${LIBS}
listener: listener.c hdr.h timesPrint.o
cc ${CFLAGS} $@.c -o $@ ${LIBS}
timesPrint.o: hdr.h
run:
talker >>stats
//E*O*F Makefile//
echo x - hdr.h
cat > "hdr.h" << '//E*O*F hdr.h//'
/* imported definitions */
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/time.h>
/* constants */
#define NO_BYTES (1024*1024)
#define MIN_CHUNK 128
#define MAX_CHUNK 4096
#define MAX_ERRORS 5
/* global variables */
char buf[MAX_CHUNK];
struct timeval start_time;
struct timeval end_time;
struct timezone time_zone;
/* function declarations */
void timesPrint();
/* dummy error handling macros */
#define ErrorMsg(File,Line,Format,Valuea,Valueb) \
fprintf(stderr, "%s, line %d:", File, Line); \
fprintf(stderr, Format, Valuea, Valueb); \
fprintf(stderr, "\n" ); \
fflush (stderr);
#define ErrorSystem(File,Line,Fileno,Rc) \
{ \
extern int errno; \
extern char* sys_errlist[]; \
\
if (Rc < 0) { \
ErrorMsg(File, Line, \
"negative return code (%d) returned by system call for fd %d", \
Rc, Fileno); \
ErrorMsg(File, Line, \
"errno was %d. corresponding msg is '%s'", \
errno, sys_errlist[errno]); \
} \
}
/*
* Note: I have a real error handling library but it is too difficult to
* distribute for something as small as this. mwherman at watcgl
*/
//E*O*F hdr.h//
echo x - listener.c
cat > "listener.c" << '//E*O*F listener.c//'
#include "hdr.h"
main(argc, argv)
int argc;
char * argv[];
{
FILE * earpiece = stdin;
int chunk;
int rc;
int no_bytes;
int check_value;
int no_errors;
no_errors = 0;
rc = read( fileno(earpiece), &chunk, sizeof(chunk) );
ErrorSystem( __FILE__, __LINE__, fileno(earpiece), rc );
# ifdef
fprintf( stderr, "%s, line %d:chunk %d\n", __FILE__, __LINE__, chunk );
fflush( stderr );
# endif
check_value = chunk;
(void) gettimeofday( &start_time, &time_zone );
for (no_bytes = 0; ;no_bytes += rc) {
rc = read( fileno(earpiece), buf, chunk );
ErrorSystem( __FILE__, __LINE__, fileno(earpiece), rc );
if (rc == 0)
break;
if ((rc != chunk) && (no_errors < MAX_ERRORS)) {
ErrorMsg( __FILE__, __LINE__,
"warning:partial chunk %d != chunk %d", rc, chunk );
no_errors++;
}
# ifdef DEBUG
if (no_bytes % check_value == 0) {
fprintf( stderr, "%s, line %d:chunk, no_bytes %d, %d\n",
__FILE__, __LINE__, chunk, no_bytes );
fflush( stderr );
check_value *= 4;
}
# endif
}
(void) gettimeofday( &end_time, &time_zone );
# ifdef DEBUG
fprintf( stderr, "%-8s:no_bytes %d\n", "listener", no_bytes );
# endif
(void) timesPrint( argv[0], chunk, start_time, end_time );
fflush( stderr );
}
//E*O*F listener.c//
echo x - stats.example
cat > "stats.example" << '//E*O*F stats.example//'
talker :chunk 4096 sec 2.860000
listener:chunk 4096 sec 2.700000
talker :chunk 3968 sec 4.100000
listener:chunk 3968 sec 4.010000
talker :chunk 3840 sec 4.040000
listener:chunk 3840 sec 3.850000
talker :chunk 3712 sec 4.220000
listener:chunk 3712 sec 3.970000
talker :chunk 3584 sec 6.130000
listener:chunk 3584 sec 5.930000
talker :chunk 3456 sec 6.030000
listener:chunk 3456 sec 5.870000
talker :chunk 3328 sec 6.920000
listener:chunk 3328 sec 6.660000
talker :chunk 3200 sec 6.190000
listener:chunk 3200 sec 5.970000
talker :chunk 3072 sec 3.190000
listener:chunk 3072 sec 3.010000
talker :chunk 2944 sec 5.830000
listener:chunk 2944 sec 5.640000
talker :chunk 2816 sec 7.410000
listener:chunk 2816 sec 7.170000
talker :chunk 2688 sec 4.300000
listener:chunk 2688 sec 4.130000
talker :chunk 2560 sec 4.750000
listener:chunk 2560 sec 4.420000
talker :chunk 2432 sec 7.590000
listener:chunk 2432 sec 7.380000
talker :chunk 2304 sec 5.550000
listener:chunk 2304 sec 5.360000
talker :chunk 2176 sec 4.200000
listener:chunk 2176 sec 3.970000
talker :chunk 2048 sec 3.430000
listener:chunk 2048 sec 3.280000
talker :chunk 1920 sec 5.430000
listener:chunk 1920 sec 5.350000
talker :chunk 1792 sec 8.240000
listener:chunk 1792 sec 8.000000
talker :chunk 1664 sec 11.410000
listener:chunk 1664 sec 11.320000
talker :chunk 1536 sec 7.760000
listener:chunk 1536 sec 7.540000
talker :chunk 1408 sec 7.380000
listener:chunk 1408 sec 7.050000
talker :chunk 1280 sec 8.070000
listener:chunk 1280 sec 7.870000
talker :chunk 1152 sec 8.760000
listener:chunk 1152 sec 8.570000
talker :chunk 1024 sec 7.390000
listener:chunk 1024 sec 7.220000
talker :chunk 896 sec 13.210000
listener:chunk 896 sec 13.320000
talker :chunk 768 sec 14.360000
listener:chunk 768 sec 14.160000
talker :chunk 640 sec 18.630000
listener:chunk 640 sec 18.410000
talker :chunk 512 sec 15.470000
listener:chunk 512 sec 14.820000
talker :chunk 384 sec 13.110000
listener:chunk 384 sec 12.890000
talker :chunk 256 sec 17.840000
listener:chunk 256 sec 17.640000
talker :chunk 128 sec 35.080000
listener:chunk 128 sec 34.850000
//E*O*F stats.example//
echo x - talker.c
cat > "talker.c" << '//E*O*F talker.c//'
#include <stdio.h>
#include "hdr.h"
char buf[MAX_CHUNK];
main(argc, argv)
int argc;
char * argv[];
{
FILE * mouthpiece;
int chunk;
int rc;
int no_bytes;
for (no_bytes = 0; no_bytes < MAX_CHUNK; no_bytes++)
buf[no_bytes] = -1;
for (chunk = MAX_CHUNK; chunk >= MIN_CHUNK; chunk -= 128) {
mouthpiece = (FILE *) popen( "listener", "w" );
# ifdef DEBUG
fprintf( stderr, "%s, line %d:mouthpiece %d\n",
__FILE__, __LINE__, mouthpiece );
fflush( stderr );
fprintf( stderr, "%s, line %d:fileno(mouthpiece) %d\n",
__FILE__, __LINE__, fileno(mouthpiece) );
fflush( stderr );
# endif
if (mouthpiece == (FILE *) NULL)
ErrorSystem( __FILE__, __LINE__, -1, -1 );
rc = write( fileno(mouthpiece), &chunk, sizeof(chunk) );
ErrorSystem( __FILE__, __LINE__, fileno(mouthpiece), rc );
(void) gettimeofday( &start_time, &time_zone );
for (no_bytes = 0; no_bytes < (NO_BYTES-chunk); no_bytes += chunk) {
# ifdef DEBUG
if (no_bytes > 1000*1000)
fprintf( stderr, "%s, line %d:no_bytes %d NO_BYTES %d\n",
__FILE__, __LINE__, no_bytes, NO_BYTES );
# endif
rc = write( fileno(mouthpiece), buf, chunk );
ErrorSystem( __FILE__, __LINE__, fileno(mouthpiece), rc );
}
if (no_bytes < NO_BYTES) {
# ifdef DEBUG
fprintf( stderr, "%s, line %d:NO_BYTES-no_bytes %d\n",
__FILE__, __LINE__, NO_BYTES-no_bytes );
# endif
rc = write( fileno(mouthpiece), buf, NO_BYTES-no_bytes );
ErrorSystem( __FILE__, __LINE__, fileno(mouthpiece), rc );
no_bytes += (NO_BYTES-no_bytes);
}
(void) gettimeofday( &end_time, &time_zone );
# ifdef DEBUG
fprintf( stderr, "%-8s:no_bytes %d\n", "talker", no_bytes );
# endif
(void) timesPrint( "talker", chunk, start_time, end_time );
rc = pclose( mouthpiece );
ErrorSystem( __FILE__, __LINE__, fileno(mouthpiece), rc );
}
}
//E*O*F talker.c//
echo x - timesPrint.c
cat > "timesPrint.c" << '//E*O*F timesPrint.c//'
#include "hdr.h"
void
timesPrint( routine, chunk, start_time, end_time )
char * routine;
int chunk;
struct timeval start_time;
struct timeval end_time;
{
int rc;
extern int errno;
while( (rc=symlink("/dev/null","timesPrint.lock")) != 0) {
if (errno != EEXIST) ErrorSystem( __FILE__, __LINE__, -1, rc );
}
printf( "%-8s:chunk %d sec %f\n",
routine, chunk,
(float)(end_time.tv_sec - start_time.tv_sec) +
(float)(end_time.tv_usec - start_time.tv_usec) * 1e-6 );
fflush( stdout );
rc = unlink("timesPrint.lock");
ErrorSystem( __FILE__, __LINE__, -1, rc );
}
//E*O*F timesPrint.c//
exit 0
More information about the Comp.sources.unix
mailing list