>Number:         6476
>Category:       user
>Synopsis:       sum/md5/etc. pessimaly use file I/O
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Thu Sep 30 05:10:01 GMT 2010
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
        System      : OpenBSD 4.7
        Details     : OpenBSD 4.7-current (ook.mp) #3: Mon Sep 27 02:47:48 EDT 
2010
                         [email protected]:/usr/src/sys/arch/amd64/compile/ook.mp

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:
        The OS can give a user mode program a good hint about optimizing
        file I/O: st_blksize. stdio uses this. Many programs doing I/O
        do not, giving very bad performance.
>How-To-Repeat:
        Run sum on a large file. It makes 1 syscall per block.
>Fix:
        Use code like exists in stdio to stat the input file
        Allocate buffers according to that amount.
        *******NOTE****** using st_blksize is good.
        Using 2 or 3 x st_blksize gives a substantial speedup.
        I suggest that st_blksize be adjusted by 2x for a large
        speedup in utility I/O. The "cp" speedup debate of a few
        months past would not be an issue if cp used st_blksize.
        I would be happy to write a small set of routines
        based on the existing stdio ones for use in programs
        which don't want stdio for various reasons.
        Diff:
--- md5.c.old   Fri Aug  6 23:11:09 2010
+++ md5.c       Fri Aug  6 23:18:09 2010
@@ -22,6 +22,7 @@
 
 #include <sys/param.h>
 #include <sys/queue.h>
+#include <sys/stat.h>
 #include <netinet/in.h>
 #include <ctype.h>
 #include <err.h>
@@ -477,7 +478,9 @@
        struct hash_function *hf;
        int fd;
        ssize_t nread;
-       u_char data[BUFSIZ];
+       size_t bufsiz;
+       struct stat stat_buf;
+       u_char *data;
        char digest[MAX_DIGEST_LEN + 1];
 
        if (strcmp(file, "-") == 0)
@@ -486,6 +489,17 @@
                warn("cannot open %s", file);
                return;
        }
+       if (fstat(fd, &stat_buf) == -1) {
+               warn("cannot stat %s", file);
+               bufsiz = BUFSIZ;
+       } else if (stat_buf.st_blksize == 0)
+               bufsiz = BUFSIZ;
+       else
+               bufsiz = 4 * stat_buf.st_blksize;
+       if ((data = malloc(bufsiz)) == NULL) {
+               warn("cannot allocate read buffer for %s\n", file);
+               return;
+       }
 
        if (echo)
                fflush(stdout);
@@ -495,12 +509,13 @@
                        err(1, NULL);
                hf->init(hf->ctx);
        }
-       while ((nread = read(fd, data, sizeof(data))) > 0) {
+       while ((nread = read(fd, data, bufsiz)) > 0) {
                if (echo)
                        write(STDOUT_FILENO, data, (size_t)nread);
                TAILQ_FOREACH(hf, hl, tailq)
                        hf->update(hf->ctx, data, (unsigned int)nread);
        }
+       free(data);
        if (nread == -1) {
                warn("%s: read error", file);
                if (fd != STDIN_FILENO)
@@ -538,7 +553,9 @@
        FILE *fp;
        ssize_t nread;
        size_t len;
-       u_char data[BUFSIZ];
+       size_t bufsiz;
+       struct stat stat_buf;
+       u_char *data;
        union ANY_CTX context;
        struct hash_function *hf;
 
@@ -660,10 +677,23 @@
                        error = 1;
                        continue;
                }
+               if (fstat(fd, &stat_buf) == -1) {
+                       warn("cannot stat %s", file);
+                       bufsiz = BUFSIZ;
+               } else if (stat_buf.st_blksize == 0)
+                       bufsiz = BUFSIZ;
+               else
+                       bufsiz = stat_buf.st_blksize;
+               if ((data = malloc(bufsiz)) == NULL) {
+                       warn("cannot allocate read buffer for %s\n", file);
+                       error = 1;
+                       continue;
+               }
 
                hf->init(&context);
-               while ((nread = read(fd, data, sizeof(data))) > 0)
+               while ((nread = read(fd, data, bufsiz)) > 0)
                        hf->update(&context, data, (unsigned int)nread);
+               free(data);
                if (nread == -1) {
                        warn("%s: read error", file);
                        error = 1;


dmesg:
OpenBSD 4.7-current (ook.mp) #3: Mon Sep 27 02:47:48 EDT 2010
    [email protected]:/usr/src/sys/arch/amd64/compile/ook.mp
real mem = 2949513216 (2812MB)
avail mem = 2857172992 (2724MB)
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xf0100 (55 entries)
bios0: vendor Award Software International, Inc. version "F2" date 04/30/2009
bios0: Gigabyte Technology Co., Ltd. GA-MA790GP-UD4H
acpi0 at bios0: rev 0
acpi0: tables DSDT FACP SSDT HPET MCFG TAMG APIC
acpi0: wakeup devices USB0(S3) USB1(S3) USB2(S3) USB3(S3) USB4(S3) USB5(S3) 
USB6(S3) SBAZ(S4) P2P_(S5) PCE2(S4) PCE3(S4) PCE4(S4) PCE5(S4) PCE6(S4) 
PCE7(S4) PCE9(S4) PCEA(S4) PCEB(S4) PCEC(S4) PS2M(S5) PS2K(S5) PCI0(S5)
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpihpet0 at acpi0: 14318180 Hz
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: AMD Athlon(tm) 64 X2 Dual Core Processor 5600+, 2913.64 MHz
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,CX16,NXE,MMXX,FFXSR,LONG,3DNOW2,3DNOW
cpu0: 64KB 64b/line 2-way I-cache, 64KB 64b/line 2-way D-cache, 512KB 64b/line 
16-way L2 cache
cpu0: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu0: DTLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu0: apic clock running at 200MHz
cpu1 at mainbus0: apid 1 (application processor)
cpu1: AMD Athlon(tm) 64 X2 Dual Core Processor 5600+, 2913.27 MHz
cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,CX16,NXE,MMXX,FFXSR,LONG,3DNOW2,3DNOW
cpu1: 64KB 64b/line 2-way I-cache, 64KB 64b/line 2-way D-cache, 512KB 64b/line 
16-way L2 cache
cpu1: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu1: DTLB 32 4KB entries fully associative, 8 4MB entries fully associative
ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 21, 24 pins
ioapic0: misconfigured as apic 0, remapped to apid 2
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 4 (P2P_)
acpiprt2 at acpi0: bus -1 (PCE2)
acpiprt3 at acpi0: bus -1 (PCE3)
acpiprt4 at acpi0: bus -1 (PCE4)
acpiprt5 at acpi0: bus -1 (PCE5)
acpiprt6 at acpi0: bus 2 (PCE6)
acpiprt7 at acpi0: bus -1 (PCE7)
acpiprt8 at acpi0: bus -1 (PCE9)
acpiprt9 at acpi0: bus 3 (PCEA)
acpiprt10 at acpi0: bus -1 (PCEB)
acpiprt11 at acpi0: bus -1 (PCEC)
acpiprt12 at acpi0: bus 1 (AGP_)
acpicpu0 at acpi0: PSS
acpicpu1 at acpi0: PSS
acpibtn0 at acpi0: PWRB
cpu0: PowerNow! K8 2913 MHz: speeds: 2900 2800 2600 2400 2200 2000 1800 1000 MHz
pci0 at mainbus0 bus 0
mem address conflict 0xe0000000/0x20000000
pchb0 at pci0 dev 0 function 0 "AMD RS780 Host" rev 0x00
ppb0 at pci0 dev 1 function 0 "AMD RS780 PCIE" rev 0x00
pci1 at ppb0 bus 1
vga1 at pci1 dev 5 function 0 "ATI Radeon HD 3300" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
radeondrm0 at vga1: apic 2 int 18 (irq 11)
drm0 at radeondrm0
azalia0 at pci1 dev 5 function 1 "ATI RS780 HD Audio" rev 0x00: apic 2 int 19 
(irq 7)
azalia0: no supported codecs
azalia0: initialization failure, detaching
ppb1 at pci0 dev 6 function 0 "AMD RS780 PCIE" rev 0x00: apic 2 int 18 (irq 11)
pci2 at ppb1 bus 2
jmb0 at pci2 dev 0 function 0 "JMicron JMB363 IDE/SATA" rev 0x03
ahci0 at jmb0: apic 2 int 18 (irq 11), AHCI 1.0
scsibus0 at ahci0: 32 targets
pciide0 at jmb0: DMA, channel 0 wired to native-PCI, channel 1 wired to 
native-PCI
pciide0: using apic 2 int 18 (irq 11) for native-PCI interrupt
pciide0: channel 0 disabled (no drives)
pciide0: channel 1 disabled (no drives)
ppb2 at pci0 dev 10 function 0 "AMD RS780 PCIE" rev 0x00: apic 2 int 18 (irq 11)
pci3 at ppb2 bus 3
re0 at pci3 dev 0 function 0 "Realtek 8168" rev 0x02: RTL8168C/8111C (0x3c00), 
apic 2 int 18 (irq 11), address 00:24:1d:19:01:0d
rgephy0 at re0 phy 7: RTL8169S/8110S PHY, rev. 2
ahci1 at pci0 dev 17 function 0 "ATI SBx00 SATA" rev 0x00: apic 2 int 22 (irq 
10), AHCI 1.1
scsibus1 at ahci1: 32 targets
sd0 at scsibus1 targ 0 lun 0: <ATA, Hitachi HDT72101, ST6O> SCSI3 0/direct fixed
sd0: 953868MB, 512 bytes/sec, 1953523055 sec total
sd1 at scsibus1 targ 1 lun 0: <ATA, ST3500630AS, 3.AA> SCSI3 0/direct fixed
sd1: 476940MB, 512 bytes/sec, 976773168 sec total
sd2 at scsibus1 targ 2 lun 0: <ATA, Hitachi HDT72101, ST6O> SCSI3 0/direct fixed
sd2: 953869MB, 512 bytes/sec, 1953525168 sec total
sd3 at scsibus1 targ 3 lun 0: <ATA, WDC WD10EACS-00Z, 01.0> SCSI3 0/direct fixed
sd3: 953869MB, 512 bytes/sec, 1953525168 sec total
ohci0 at pci0 dev 18 function 0 "ATI SB700 USB" rev 0x00: apic 2 int 16 (irq 
5), version 1.0, legacy support
ohci1 at pci0 dev 18 function 1 "ATI SB700 USB" rev 0x00: apic 2 int 16 (irq 
5), version 1.0, legacy support
ehci0 at pci0 dev 18 function 2 "ATI SB700 USB2" rev 0x00: apic 2 int 17 (irq 3)
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 "ATI EHCI root hub" rev 2.00/1.00 addr 1
ohci2 at pci0 dev 19 function 0 "ATI SB700 USB" rev 0x00: apic 2 int 18 (irq 
11), version 1.0, legacy support
ohci3 at pci0 dev 19 function 1 "ATI SB700 USB" rev 0x00: apic 2 int 18 (irq 
11), version 1.0, legacy support
ehci1 at pci0 dev 19 function 2 "ATI SB700 USB2" rev 0x00: apic 2 int 19 (irq 7)
usb1 at ehci1: USB revision 2.0
uhub1 at usb1 "ATI EHCI root hub" rev 2.00/1.00 addr 1
piixpm0 at pci0 dev 20 function 0 "ATI SBx00 SMBus" rev 0x3a: SMI
iic0 at piixpm0
spdmem0 at iic0 addr 0x50: 2GB DDR2 SDRAM non-parity PC2-6400CL5
spdmem1 at iic0 addr 0x51: 2GB DDR2 SDRAM non-parity PC2-6400CL5
pciide1 at pci0 dev 20 function 1 "ATI SB700 IDE" rev 0x00: DMA, channel 0 
configured to compatibility, channel 1 configured to compatibility
wdcattach: ch_drive_flags 0x1 0x2
wd0 at pciide1 channel 1 drive 0: <STT_FTM16GL25V>
wdc_probe_caps: wdc_cap 0x41f cf_flags 0x0
wdc_probe_caps: atap_oldpiotiming=2
wdc_probe_caps: atap_extensions=0x7, atap_piomode_supp=0x3, 
atap_dmamode_supp=0x7, atap_udmamode_supp=0x7f
ata_set_mode: mode=0xc, flags=0x10
ata_set_mode: after wdc_exec_command() wdc_c.flags=0x30
ata_set_mode: mode=0x22, flags=0x10
ata_set_mode: after wdc_exec_command() wdc_c.flags=0x30
ata_set_mode: mode=0x46, flags=0x10
ata_set_mode: after wdc_exec_command() wdc_c.flags=0x30
wd0: 1-sector PIO, LBA48, 15271MB, 31275119 sectors
atapiscsi0 at pciide1 channel 1 drive 1
wdc_probe_caps: wdc_cap 0x41f cf_flags 0x0
wdc_probe_caps: atap_oldpiotiming=2
wdc_probe_caps: atap_extensions=0x6, atap_piomode_supp=0x3, 
atap_dmamode_supp=0x7, atap_udmamode_supp=0x3f
ata_set_mode: mode=0xc, flags=0x10
ata_set_mode: after wdc_exec_command() wdc_c.flags=0x30
ata_set_mode: mode=0x22, flags=0x10
ata_set_mode: after wdc_exec_command() wdc_c.flags=0x30
ata_set_mode: mode=0x45, flags=0x10
ata_set_mode: after wdc_exec_command() wdc_c.flags=0x30
general config 85c0 capabilities 0f00 driver caps 0040
scsibus2 at atapiscsi0: 2 targets
wdc_atapi_send_cmd pciide1:1:1 start
wdc_atapi_send_cmd pciide1:1:1  00 00 00 00 00 00
wdc_atapi_start pciide1:1:1, scsi flags 0x1c3, ATA flags 0x22
wdc_atapi_ctrl pciide1:1:1 state 0
wdc_atapi_ctrl pciide1:1:1 state 1
wdc_atapi_ctrl pciide1:1:1 state 3
wdc_atapi_ctrl pciide1:1:1 state 4
wdc_atapi_ctrl pciide1:1:1 state 5
wdc_atapi_ctrl pciide1:1:1 state 7
wdc_atapi_start pciide1:1:1, scsi flags 0x1c3, ATA flags 0x22
wdc_atapi_send_packet pciide1:1:1 command sent
00 00 00 00 00 00 00 00 00 00 00 00 : PHASE_CMDOUT
Phase 2, (0x51<DRDY,DSC,ERR>, 0x3) PHASE_COMPLETED
Atapi error: 6 
wdc_atapi_start pciide1:1:1, scsi flags 0x1c3, ATA flags 0xa2
wdc_atapi_send_packet pciide1:1:1 command sent
03 00 00 00 20 00 00 00 00 00 00 00 : PHASE_CMDOUT
Phase 1, (0x58<DRDY,DSC,DRQ>, 0x2) wdc_atapi_intr: c_bcount 32 len 18 st 
0x58<DRDY,DSC,DRQ> err 0x60 ire 0x2
Phase 1, (0x50<DRDY,DSC>, 0x3) PHASE_COMPLETED
wdc_atapi_intr: bcount value is 14 after io
wdc_atapi_intr: wdc_atapi_done() (end), error 0x1 
wdc_atapi_done pciide1:1:1: flags 0xa2 error 0x1
wdc_atapi_send_cmd pciide1:1:1 start
wdc_atapi_send_cmd pciide1:1:1  12 00 00 00 24 00
wdc_atapi_start pciide1:1:1, scsi flags 0x823, ATA flags 0x22
wdc_atapi_send_packet pciide1:1:1 command sent
12 00 00 00 24 00 00 00 00 00 00 00 : PHASE_CMDOUT
Phase 1, (0x58<DRDY,DSC,DRQ>, 0x2) wdc_atapi_intr: c_bcount 36 len 36 st 
0x58<DRDY,DSC,DRQ> err 0x60 ire 0x2
Phase 1, (0x50<DRDY,DSC>, 0x3) PHASE_COMPLETED
wdc_atapi_intr: wdc_atapi_done() (end), error 0x0 
wdc_atapi_done pciide1:1:1: flags 0x22 error 0x0
wdc_atapi_send_cmd pciide1:1:1 start
wdc_atapi_send_cmd pciide1:1:1  00 00 00 00 00 00
wdc_atapi_start pciide1:1:1, scsi flags 0x1c3, ATA flags 0x22
wdc_atapi_send_packet pciide1:1:1 command sent
00 00 00 00 00 00 00 00 00 00 00 00 : PHASE_CMDOUT
Phase 2, (0x50<DRDY,DSC>, 0x3) PHASE_COMPLETED
wdc_atapi_intr: wdc_atapi_done() (end), error 0x0 
wdc_atapi_done pciide1:1:1: flags 0x22 error 0x0
cd0 at scsibus2 targ 0 lun 0: <TSSTcorp, CDDVDW SH-S203B, SB03> ATAPI 5/cdrom 
removable
wdc_atapi_send_cmd pciide1:1:1 start
wdc_atapi_send_cmd pciide1:1:1 start
wd0(pciide1:1:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 6
cd0(pciide1:1:1): using PIO mode 4, DMA mode 2, Ultra-DMA mode 5
azalia1 at pci0 dev 20 function 2 "ATI SBx00 HD Audio" rev 0x00: apic 2 int 16 
(irq 5)
azalia1: codecs: Realtek ALC885
audio0 at azalia1
pcib0 at pci0 dev 20 function 3 "ATI SB700 ISA" rev 0x00
ppb3 at pci0 dev 20 function 4 "ATI SB600 PCI" rev 0x00
pci4 at ppb3 bus 4
ohci4 at pci0 dev 20 function 5 "ATI SB700 USB" rev 0x00: apic 2 int 18 (irq 
11), version 1.0, legacy support
pchb1 at pci0 dev 24 function 0 "AMD AMD64 0Fh HyperTransport" rev 0x00
pchb2 at pci0 dev 24 function 1 "AMD AMD64 0Fh Address Map" rev 0x00
pchb3 at pci0 dev 24 function 2 "AMD AMD64 0Fh DRAM Cfg" rev 0x00
kate0 at pci0 dev 24 function 3 "AMD AMD64 0Fh Misc Cfg" rev 0x00: core rev 
BH-G2
usb2 at ohci0: USB revision 1.0
uhub2 at usb2 "ATI OHCI root hub" rev 1.00/1.00 addr 1
usb3 at ohci1: USB revision 1.0
uhub3 at usb3 "ATI OHCI root hub" rev 1.00/1.00 addr 1
usb4 at ohci2: USB revision 1.0
uhub4 at usb4 "ATI OHCI root hub" rev 1.00/1.00 addr 1
usb5 at ohci3: USB revision 1.0
uhub5 at usb5 "ATI OHCI root hub" rev 1.00/1.00 addr 1
isa0 at pcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
midi0 at pcppi0: <PC speaker>
spkr0 at pcppi0
it0 at isa0 port 0x2e/2: IT8718F rev 5, EC port 0x228
usb6 at ohci4: USB revision 1.0
uhub6 at usb6 "ATI OHCI root hub" rev 1.00/1.00 addr 1
mtrr: Pentium Pro MTRR support
vscsi0 at root
scsibus3 at vscsi0: 256 targets
softraid0 at root
root on sd0a swap on sd0b dump on sd0b


>Release-Note:
>Audit-Trail:
>Unformatted:

Reply via email to