From owner-freebsd-current@FreeBSD.ORG Wed Aug 3 16:32:44 2005 Return-Path: X-Original-To: current@FreeBSD.ORG Delivered-To: freebsd-current@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0DB0C16A41F for ; Wed, 3 Aug 2005 16:32:44 +0000 (GMT) (envelope-from sobomax@portaone.com) Received: from www.portaone.com (support.portaone.com [195.70.151.35]) by mx1.FreeBSD.org (Postfix) with ESMTP id 66EB243D45 for ; Wed, 3 Aug 2005 16:32:43 +0000 (GMT) (envelope-from sobomax@portaone.com) Received: from [192.168.0.49] (lesnik.portaone.com [195.140.246.50] (may be forged)) (authenticated bits=0) by www.portaone.com (8.12.11/8.12.11) with ESMTP id j73FwowN025820 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 3 Aug 2005 17:58:50 +0200 (CEST) (envelope-from sobomax@portaone.com) Message-ID: <42F0E9B2.9080208@portaone.com> Date: Wed, 03 Aug 2005 18:58:42 +0300 From: Maxim Sobolev Organization: Porta Software Ltd User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Dan Nelson References: <42F0CCD5.9090200@portaone.com> <20050803150117.GD93405@dan.emsphone.com> In-Reply-To: <20050803150117.GD93405@dan.emsphone.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV 0.86.2/1002/Wed Aug 3 12:29:36 2005 on www.portaone.com X-Virus-Status: Clean X-Spam-Status: No, score=-5.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham version=3.0.0 X-Spam-Checker-Version: SpamAssassin 3.0.0 (2004-09-13) on www.portaone.com Cc: "current@freebsd.org" Subject: Re: Sub-optimal libc's read-ahead buffering behaviour X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Maxim.Sobolev@portaone.com List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Aug 2005 16:32:44 -0000 Checking the actual code confirm your point, thank you! However, I think that the current behaviour is at best inconsistent, since it in fact does buffering of character devices in some cases but does not in some others. In my example it reads 4096 bytes instead of requested 512 at each request, but when the program does fseek it rejects part of that buffer and does re-positioning and re-reading. Very confusing behaviour IMHO. -Maxim Dan Nelson wrote: > In the last episode (Aug 03), Maxim Sobolev said: > >>I have found the scenario in which our libc behaves utterly >>suboptimally. Consider the following piece of code reads and >>processes every other 512-bytes block in a file (error handling >>intentionally omitted): >> >>What I have discovered in this case is that libc reads 4096 bytes >>from the file for *each* fread(3) call, despite the fact that it can >>only do one actual read(2) for every fourth fread(3) and satisfy the >>rest from the internal buffer (4096 bytes). However, if I replace >>fseek(3) with just another dummy fread(3) everything works as >>expected - libc does only one read for every 8 fread(3) calls (4 >>dummy and 4 real). >> >>Is it something which should be fixed or are there some subtle >>reasons for the current behaviour? > > > I don't think stdio buffers character devices. If you try it again, > opening a regular file (I tried with /boot/kernel/kernel), you'll see > much better behaviour. There are still some unnecessary seeks though: > > truss ./a.out > > open("/boot/kernel/kernel",O_RDONLY,0666) = 3 (0x3) > fstat(3,{mode=-r-xr-xr-x ,inode=12295,size=4372853,blksize=8192}) = 0 (0x0) > readlink("/etc/malloc.conf","AJ",63) = 2 (0x2) > issetugid() = 0 (0x0) > mmap(0x0,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 672555008 (0x28166000) > break(0x804b000) = 0 (0x0) > break(0x804d000) = 0 (0x0) > read(3,"\^?ELF\^A\^A\^A\t\0\0\0\0\0\0\0\0\^B\0"...,8192) = 8192 (0x2000) > read(3,"\0\0\0\0\0\0\0\0\M-u\^E\0\0\M-+\^V\0\0q"...,8192) = 8192 (0x2000) > exit(0x0) > > truss ./a.out 1 > > open("/boot/kernel/kernel",O_RDONLY,0666) = 3 (0x3) > fstat(3,{mode=-r-xr-xr-x ,inode=12295,size=4372853,blksize=8192}) = 0 (0x0) > readlink("/etc/malloc.conf","AJ",63) = 2 (0x2) > issetugid() = 0 (0x0) > mmap(0x0,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 672555008 (0x28166000) > break(0x804b000) = 0 (0x0) > break(0x804d000) = 0 (0x0) > read(3,"\^?ELF\^A\^A\^A\t\0\0\0\0\0\0\0\0\^B\0"...,8192) = 8192 (0x2000) > lseek(3,0x0,SEEK_CUR) = 8192 (0x2000) > lseek(3,0x2000,SEEK_SET) = 8192 (0x2000) > read(3,"\0\0\0\0\0\0\0\0\M-u\^E\0\0\M-+\^V\0\0q"...,8192) = 8192 (0x2000) > exit(0x0) >