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!thomson
Ttang.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"); } }