lkml.org 
[lkml]   [1996]   [Apr]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: File read-ahead and Linux-1.3.85

    Matti,

    On Mon, 8 Apr 1996, Matti E Aarnio wrote:

    > > Linux-1.3.85 also does
    > ....
    > > - file read-ahead code update
    >
    > This should have speeded up the system, right ?
    > (Such claim was made by the author of that patch..)

    I am sure that you did not try my previous patch.
    My patch was experimental but worked fine.
    Linux patch for asynchronous read-ahead is quite aesthetic but quite bad.

    >
    > -------Sequential Output-------- ---Sequential Input-- --Random--
    > -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
    > Machine MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU /sec %CPU
    > Lnx1380 100 3221 60.4 2973 19.9 1150 13.9 2300 44.1 2844 12.9 45.9 2.3
    > Lnx1384 180 2395 43.4 2714 17.2 1339 16.7 2519 47.2 3253 14.6 69.2 2.9
    > Lnx1385 180 2520 44.9 3204 19.8 1258 16.1 2721 56.6 3220 16.0 70.1 3.0
    >
    > This machine is a 266 MHz Alpha-XL with integrated NCR 53C810, and
    > Seagate ST31230N SCSI-disk. At the last two tests the system had
    > 128 MB memory, while with the first one there was propably 32 MB memory.
    >
    > My point, either we are limited by the disk, or perhaps the NCR-driver
    > is not as good as it could be... The read-ahead does not help noticeably.
    > ...
    > > Now, go test it out to see if I broke something else while the above got
    > > fixed..
    > > Linus
    >
    > /Matti Aarnio <mea@utu.fi>
    >

    I have done some tests with 1.3.85 and 1.3.84 patched.
    P90/24MB/IBMS12/NCR53C810/BSD driver
    (I skipped seekers)

    Here are the results of those tests with Bonnie:
    ------------------------------------------------

    Messages "XXXXXX ...." are some statistics printed by the driver about
    xfer sizes.

    Here is the output I get with 1.3.85 unpatched:
    -----------------------------------------------
    Writing with putc()...
    XXXXXXXXXX - Xfer length min=1024 max=124928 average=96327
    done
    Rewriting...
    XXXXXXXXXX - Xfer length min=1024 max=124928 average=14494
    done
    Writing intelligently...
    XXXXXXXXXX - Xfer length min=1024 max=124928 average=111884
    done
    Reading with getc()...
    XXXXXXXXXX - Xfer length min=1024 max=24576 average=4164
    done
    Reading intelligently...
    XXXXXXXXXX - Xfer length min=1024 max=16384 average=7973
    done


    Here is the output I get with 1.3.84 patched for asynchronous read-ahead:
    -------------------------------------------------------------------------

    Writing with putc()...
    XXXXXXXXXX - Xfer length min=1024 max=124928 average=95868
    done
    Rewriting...
    XXXXXXXXXX - Xfer length min=1024 max=124928 average=33426
    done
    Writing intelligently...
    XXXXXXXXXX - Xfer length min=1024 max=124928 average=112278
    done
    Reading with getc()...
    XXXXXXXXXX - Xfer length min=1024 max=36864 average=31538
    done
    Reading intelligently...
    XXXXXXXXXX - Xfer length min=1024 max=36864 average=28550
    done

    -------Sequential Output-------- ---Sequential Input-- --Random--
    -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
    Machine MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU
    1.3.85 200 3015 89.3 3308 36.8 1256 24.5 2383 87.0 3597 28.3
    1.3.84+P 200 3044 90.8 3491 39.0 1549 30.4 2855 88.8 3867 30.0

    1.3.85 : linux 1.3.85 with Linus's interpretation of asynchronous read-ahead.
    1.3.84+P : linux 1.3.84 with my patch for asynchronous read-ahead.

    What is wrong with 1.3.85:
    - CPU load for getc() (1k Read)
    - Average Xfer length with getc()
    - Speed for getc()
    - Rewrite
    - Average Xfer length for read block (8k)
    - Speed for read block


    Here is the patch against linux-1.3.84 I used for this test:
    ------------------------------------------------------------
    The previous one gives about the same performances.
    I invite you to try one of those patches.

    ---------------------------------- CUT HERE -------------------------------
    --- linux/mm/filemap.c.00 Fri Apr 5 23:00:30 1996
    +++ linux/mm/filemap.c Mon Apr 8 20:37:48 1996
    @@ -296,10 +296,14 @@
    * of the logic when it comes to error handling etc.
    */
    #define MAX_READAHEAD (PAGE_SIZE*8)
    +#define MIN_READAHEAD (PAGE_SIZE)
    int generic_file_read(struct inode * inode, struct file * filp, char * buf, int count)
    {
    int error, read;
    unsigned long pos, page_cache;
    +#ifndef ONLY_SYNCHRONOUS_READ_AHEAD
    + int try_async;
    +#endif

    if (count <= 0)
    return 0;
    @@ -308,6 +312,41 @@
    page_cache = 0;

    pos = filp->f_pos;
    +#ifndef ONLY_SYNCHRONOUS_READ_AHEAD
    + /*
    + * Dont beleive f_reada
    + */
    + if (pos <= filp->f_rapos && pos + filp->f_ralen >= filp->f_rapos) {
    + filp->f_reada = 1;
    + }
    + else if (pos+count < MIN_READAHEAD || !filp->f_rapos ||
    + pos > filp->f_rapos) {
    + filp->f_reada = 0;
    + }
    +
    + if (filp->f_reada) {
    + try_async = 1;
    + filp->f_ramax += filp->f_ramax;
    + }
    + else {
    + try_async = 0;
    + filp->f_rapos = 0;
    + filp->f_ralen = 0;
    + filp->f_ramax = 0;
    + }
    +
    + /*
    + * Compute a good value for read-ahead max
    + */
    + if (filp->f_ramax < count)
    + filp->f_ramax = count & PAGE_MASK;
    +
    + if (filp->f_ramax < MIN_READAHEAD)
    + filp->f_ramax = MIN_READAHEAD;
    + else if (filp->f_ramax > MAX_READAHEAD)
    + filp->f_ramax = MAX_READAHEAD;
    +#endif
    +
    for (;;) {
    struct page *page;
    unsigned long offset, addr, nr;
    @@ -350,6 +389,8 @@
    if (nr > count)
    nr = count;

    +#ifdef ONLY_SYNCHRONOUS_READ_AHEAD
    +/* SYNCHRONOUS only read-ahead code */
    /*
    * We may want to do read-ahead.. Do this only
    * if we're waiting for the current page to be
    @@ -373,6 +414,68 @@
    __wait_on_page(page);
    }
    unlocked_page:
    +#else /* ASYNCHRONOUS read-ahead code */
    +{
    + unsigned long max_ahead, ahead;
    + unsigned long rapos, ppos;
    +
    + ppos = pos & PAGE_MASK;
    +
    + /* Do some synchronous read-ahead */
    + if (page->locked) {
    + max_ahead = filp->f_ramax;
    + rapos = ppos;
    + }
    + /* Do some asynchronous read-ahead */
    + else {
    + rapos = filp->f_rapos & PAGE_MASK;
    + if (rapos) rapos -= PAGE_SIZE;
    +
    + if (try_async == 1 && pos <= filp->f_rapos &&
    + pos + filp->f_ralen >= filp->f_rapos) {
    + struct page *a_page;
    +
    + max_ahead = filp->f_ramax + PAGE_SIZE;
    +
    + if (rapos < inode->i_size) {
    + a_page = find_page(inode, rapos);
    + if (a_page) {
    + if (a_page->locked)
    + max_ahead = 0;
    + a_page->count--;
    + }
    + }
    + else
    + max_ahead = 0;
    + try_async = 2;
    + }
    + else {
    + max_ahead = 0;
    + }
    + }
    +
    + ahead = 0;
    + while (ahead < max_ahead) {
    + ahead += PAGE_SIZE;
    + page_cache = try_to_read_ahead(inode, rapos + ahead, page_cache);
    + }
    +
    + if (ahead > 0) {
    + filp->f_ralen = ahead;
    + /* Force unplug device in order to start asynchronous */
    + if (try_async == 2) {
    + schedule();
    + try_async = 1;
    + }
    + }
    + filp->f_rapos = rapos + ahead + PAGE_SIZE;
    +
    + if (page->locked) {
    + __wait_on_page(page);
    + }
    +}
    +#endif
    +
    if (!page->uptodate)
    goto read_page;
    if (nr > inode->i_size - pos)
    --- linux/include/linux/fs.h.00 Wed Mar 27 00:50:36 1996
    +++ linux/include/linux/fs.h Sat Apr 6 13:32:53 1996
    @@ -321,6 +321,12 @@
    unsigned short f_flags;
    unsigned short f_count;
    off_t f_reada;
    +
    +/* Added for asynchronous read-ahead patch */
    + loff_t f_rapos; /* Last read-ahead position */
    + unsigned long f_ralen; /* Length of previous read-ahead */
    + unsigned long f_ramax; /* Current max read-ahead (futur use) */
    +
    struct file *f_next, *f_prev;
    int f_owner; /* pid or -pgrp where SIGIO should be sent */
    struct inode * f_inode;
    ---------------------------------- CUT HERE -------------------------------
    Best Regards, Gerard.


    \
     
     \ /
      Last update: 2005-03-22 13:37    [W:0.032 / U:1.820 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site