Sync hdparm -t and -T options with hdparm-5.3, which seems

to produce sensible results,
This commit is contained in:
Eric Andersen 2003-08-06 08:47:59 +00:00
parent 481772a4c2
commit 50af12dbd6

View File

@ -1023,11 +1023,14 @@ static void identify (uint16_t *id_supplied, const char *devname)
#define VERSION "v5.4" #define VERSION "v5.4"
#undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ #define TIMING_MB 64
#define TIMING_BUF_MB 2 #define TIMING_BUF_MB 1
#define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
#define TIMING_BUF_COUNT (timing_MB / TIMING_BUF_MB)
#define BUFCACHE_FACTOR 2 #define BUFCACHE_FACTOR 2
#undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0; static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0;
static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0; static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0;
static int do_ctimings, do_timings = 0; static int do_ctimings, do_timings = 0;
@ -1303,13 +1306,15 @@ static int read_big_block (int fd, char *buf)
return 0; return 0;
} }
static void time_cache (int fd) static double correction = 0.0;
void time_cache (int fd)
{ {
int i;
char *buf; char *buf;
struct itimerval e1, e2; struct itimerval e1, e2;
int shmid; int shmid;
double elapsed, elapsed2; int timing_MB = TIMING_MB;
unsigned int iterations, total_MB;
if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) {
bb_perror_msg ("could not allocate sharedmem buf"); bb_perror_msg ("could not allocate sharedmem buf");
@ -1332,7 +1337,12 @@ static void time_cache (int fd)
sync(); sync();
sleep(3); sleep(3);
/* /* Calculate a correction factor for the basic
* overhead of doing a read() from the buffer cache.
* To do this, we read the data once to "cache it" and
* to force full preallocation of our timing buffer,
* and then we re-read it 10 times while timing it.
*
* getitimer() is used rather than gettimeofday() because * getitimer() is used rather than gettimeofday() because
* it is much more consistent (on my machine, at least). * it is much more consistent (on my machine, at least).
*/ */
@ -1346,42 +1356,34 @@ static void time_cache (int fd)
sync(); sync();
sleep(1); sleep(1);
/* Now do the timing */ /* Time re-reading from the buffer-cache */
iterations = 0;
getitimer(ITIMER_REAL, &e1); getitimer(ITIMER_REAL, &e1);
do { for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i) {
++iterations; if (seek_to_zero (fd)) goto quit;
if (seek_to_zero (fd) || read_big_block (fd, buf)) if (read_big_block (fd, buf)) goto quit;
goto quit; }
getitimer(ITIMER_REAL, &e2); getitimer(ITIMER_REAL, &e2);
elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) correction = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
} while (elapsed < 2.0);
total_MB = iterations * TIMING_BUF_MB;
elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
/* Now remove the lseek() and getitimer() overheads from the elapsed time */ /* Now remove the lseek() from the correction factor */
getitimer(ITIMER_REAL, &e1); getitimer(ITIMER_REAL, &e1);
do { for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i) {
if (seek_to_zero (fd)) if (seek_to_zero (fd)) goto quit;
goto quit; }
getitimer(ITIMER_REAL, &e2); getitimer(ITIMER_REAL, &e2);
elapsed2 = (e1.it_value.tv_sec - e2.it_value.tv_sec) correction -= (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
} while (--iterations);
elapsed -= elapsed2; if ((BUFCACHE_FACTOR * timing_MB) >= correction) /* more than 1MB/s */
printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",
if ((BUFCACHE_FACTOR * total_MB) >= elapsed) /* more than 1MB/s */ (BUFCACHE_FACTOR * timing_MB), correction,
printf("%3u MB in %5.2f seconds = %6.2f MB/sec\n", (BUFCACHE_FACTOR * timing_MB) / correction);
(BUFCACHE_FACTOR * total_MB), elapsed,
(BUFCACHE_FACTOR * total_MB) / elapsed);
else else
printf("%3u MB in %5.2f seconds = %6.2f kB/sec\n", printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",
(BUFCACHE_FACTOR * total_MB), elapsed, (BUFCACHE_FACTOR * timing_MB), correction,
(BUFCACHE_FACTOR * total_MB) / elapsed * 1024); (BUFCACHE_FACTOR * timing_MB) / correction * 1024);
correction /= BUFCACHE_FACTOR;
flush_buffer_cache(fd); flush_buffer_cache(fd);
sleep(1); sleep(1);
@ -1390,24 +1392,14 @@ quit:
bb_perror_msg ("could not detach sharedmem buf"); bb_perror_msg ("could not detach sharedmem buf");
} }
static void time_device (int fd) void time_device (int fd)
{ {
int i;
char *buf; char *buf;
double elapsed; double elapsed;
struct itimerval e1, e2; struct itimerval e1, e2;
int shmid; int shmid;
unsigned int max_iterations = 1024, total_MB, iterations; int timing_MB = TIMING_MB;
static long parm;
//
// get device size
//
if (do_ctimings || do_timings) {
if (ioctl(fd, BLKGETSIZE, &parm))
bb_perror_msg(" BLKGETSIZE failed");
else
max_iterations = parm / (2 * 1024) / TIMING_BUF_MB;
}
if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) {
bb_perror_msg ("could not allocate sharedmem buf"); bb_perror_msg ("could not allocate sharedmem buf");
@ -1440,24 +1432,35 @@ static void time_device (int fd)
setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL); setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL);
/* Now do the timings for real */ /* Now do the timings for real */
iterations = 0;
getitimer(ITIMER_REAL, &e1); getitimer(ITIMER_REAL, &e1);
do { for (i = TIMING_BUF_COUNT; i > 0; --i) {
++iterations; if (read_big_block (fd, buf)) goto quit;
if (read_big_block (fd, buf)) }
goto quit; getitimer(ITIMER_REAL, &e2);
getitimer(ITIMER_REAL, &e2);
elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
} while (elapsed < 3.0 && iterations < max_iterations);
total_MB = iterations * TIMING_BUF_MB; elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec)
if ((total_MB / elapsed) > 1.0) /* more than 1MB/s */ + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
printf("%3u MB in %5.2f seconds = %6.2f MB/sec\n", if (timing_MB >= elapsed) /* more than 1MB/s */
total_MB, elapsed, total_MB / elapsed); printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",
timing_MB, elapsed, timing_MB / elapsed);
else else
printf("%3u MB in %5.2f seconds = %6.2f kB/sec\n", printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",
total_MB, elapsed, total_MB / elapsed * 1024); timing_MB, elapsed, timing_MB / elapsed * 1024);
if (elapsed <= (correction * 2))
printf("Hmm.. suspicious results: probably not enough free memory for a proper test.\n");
#if 0 /* the "estimate" is just plain wrong for many systems.. */
else if (correction != 0.0) {
printf(" Estimating raw driver speed: ");
elapsed -= correction;
if (timing_MB >= elapsed) /* more than 1MB/s */
printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",
timing_MB, elapsed, timing_MB / elapsed);
else
printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",
timing_MB, elapsed, timing_MB / elapsed * 1024);
}
#endif
quit: quit:
if (-1 == shmdt(buf)) if (-1 == shmdt(buf))
bb_perror_msg ("could not detach sharedmem buf"); bb_perror_msg ("could not detach sharedmem buf");