merg@bunker.UUCP (Jim Stephenson) (11/16/83)
Hi, Does anybody know how to calculate the best interleaving factors for mkfs for different types of CPU's and different types of disks? Is there some standard technique? Andy Rodnite Mergenthaler Linotype 201 Old Country Rd. Melville, NY 11747 (516) 673-4318 ittvax!bunker!merg
thomson@utcsrgv.UUCP (Brian Thomson) (11/18/83)
m is the shuffle factor for disk block interleaving.
Usually m == 3, which means that the freelist is constructed
by linking together every third data block. It should be
large enough that no disk rotations are lost between successive
io requests, and small enough that the rotational latency between
blocks is small.
n is the number of blocks in a cylinder (== number of blocks disk
can access without head movement). The interleaving is done
on a cylinder-by-cylinder basis, so a 100 block filesystem
with m==2, n==50 would be interleaved like so:
0,2,4,6,...,48,1,3,5,...,49,50,52,54,...,96,98,51,53,55,...,97,99
Wherever I have said "block" above, I DON'T necessarily mean disk
segment (512 bytes), I mean filesystem logical block size, 1kbyte
in most 4.1BSD installations.
--
Brian Thomson, CSRG Univ. of Toronto
{linus,ihnp4,uw-beaver,floyd,utzoo}!utcsrgv!thomsonTtang.uci-750a%rand-relay@sri-unix.UUCP (11/18/83)
I think the argument m should always be 3 and n is (# of sectors per cyl./2) where you can find out the # of sectors per cylinder in a table in your driver. That's the pattern that they use to calculate n. If you take a closer look, you see that pattern. /ttang Arpanet:ttang@uci Csnet:ttang.uci@Csnet-relay Uucp:ucivax!ttang
agp@mh3bs.UUCP (11/19/83)
A few USENIX conferences ago, someone presented a
paper on computing optimal magic numbers for a
cpu/disk pair. For what it is worth, I will post
their program here:
#include <stdio.h>
#define SECTORS (disk[n].d_sec_tk * disk[n].d_surf)
struct cpu
{
char *cpu_name;
int Bps;
};
struct cpu cpu[] =
{
"PDP23", 119,
"pdp23", 119,
"11/23", 119,
"23", 119,
"PDP34", 119,
"pdp34", 119,
"11/34", 119,
"34", 119,
"PDP45", 170,
"pdp45", 170,
"11/45", 170,
"45", 170,
"PDP70", 210,
"pdp70", 210,
"11/70", 210,
"70", 210,
"VAX780", 210,
"vax780", 210,
"11/780", 210,
"780", 210,
"VAX", 210,
"vax", 210,
NULL, NULL
};
struct disk
{
char *d_name;
int d_spin;
int d_sec_tk;
int d_byte_bk;
int d_surf;
int d_cyl;
int d_tk_seek;
int d_avg_seek;
};
struct disk disk[] =
{
/* disk spin sec_tk byte_blk surf cyl tk_seek avg_seek */
"rk05", 1500, 12, 512, 2, 203, 10, 50,
"rl01", 2400, 20, 256, 2, 256, 15, 55,
"rp03", 2400, 10, 512, 20, 406, 8, 29,
"rp04", 3600, 22, 512, 19, 411, 7, 28,
"rp05", 3600, 22, 512, 19, 411, 6, 29,
"rp06", 3600, 22, 512, 19, 815, 6, 29,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
main(argc,argv)
char **argv;
{
register int k, n, i;
int block, speed;
int f_n;
for(k=0; cpu[k].cpu_name[0] != NULL; ++k) {
if(strcmp(argv[1],cpu[k].cpu_name) == 0) break;
}
if(cpu[k].Bps == NULL) {
printf("unknown cpu: %s\n",argv[1]);
exit(1);
}
for(n=0; disk[n].d_name[0] != NULL; ++n) {
block=((disk[n].d_spin/10)*disk[n].d_sec_tk);
speed=((60*(cpu[k].Bps + 1))/10);
for(i=1; i <= disk[n].d_surf; ++i) {
f_n = SECTORS / i;
if(f_n >= 100) continue;
if((SECTORS % i) == 0) {
if((f_n % disk[n].d_sec_tk) == 0) break;
}
break;
}
printf("%s: %d / %d",
disk[n].d_name,
(block / speed) + 1, SECTORS);
printf("\n");
}
}