----------------------------------------------------------------------
From: Nicolai Langfeldt <janl@math.uio.no>
Subject: libc and fseek
Date: Wed, 19 Oct 1994 13:54:58 +0100
Hello, I've been fiddeling with xdvi on linux. It was slow at
starting up. The reason it was slow is that whenever a program does
fseek libc 4.5.26 (It's very hard for me to test a later version,
sorry) wants to do lseek and read sys calls. A small test program:
----------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
FILE *f;
int t;
f=fopen("/dev/zero","r");
for (t=0;t<=1024;t++) fseek(f,t,SEEK_SET);
close(f);
}
----------------------------------------------------------------
_Every_ fseek results in one lseek and one read (strace shows):
lseek(4, 0, SEEK_SET) = 0
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
lseek(4, 0, SEEK_SET) = 0
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
lseek(4, 0, SEEK_SET) = 0
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
lseek(4, 0, SEEK_SET) = 0
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
lseek(4, 0, SEEK_SET) = 0
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024
(Yes, it lseeks to position 0 every time, then reads the same 1024
bytes every time.)
This is very slow, and imho stupid. And it is especialy slow when the
file in question is read over nfs. I counted xdvi generating 96
lseek/read pairs while reading the 1024 first bytes of a pk font file.
Replacing the fseek with a fread for the number of bytes xdvi wanted
to skip cut the execution time of the procedure in question in half.
So the penalty for lseek/read is high. It would seem to me that
making linux fseek smarter would be a definitive win. If for example
fseek just advanced the stdio internal file pointer to the right place
in the file's buffers?
For comparison SGI/Irix 5.2 had no win when converting the fseek to a
fread. However, Irix libc _did_ generate similar lseek, read system
calls when fseek was used.
On the SGI the startup time for xdvi with my benchmark document is
less than 2 seconds, with local disks or over NFS, with or without the
fseek->fread patch. Using the patched xdvi on linux with local
disks the startup time is 3 seconds, almost 15 seconds over NFS.
(I realize that the 1.0.9 nfs client is less than impressive speed
wise) W/o the patch the times are 3 seconds (same) and almost 25.
One might claim that the fault is in the NFS client then, not libc,
but I can't for the life of me see why the system should be bothered
with all those system calls.
I have tried to look at the libc source to se what must be done, but I
quickly got lost :-(
Nicolai
------------------------------
From: hjl@nynexst.com (H.J. Lu)
Subject: cross-compiler
Date: Wed, 19 Oct 94 7:37:05 EDT
> From: Jim Nance <jlnance@isscad.com>
> Subject: Can someone update the cross compiler instructions?
> Date: Tue, 18 Oct 94 16:50:27 EDT
>
>
>
> I would like to build a sun->linux cross compiler. I have done this before
> using the instructions in the GCC-FAQ, however they seem to be quite out of
> date.
>
> Specifically, I would like to be able to build either a.out or ELF executables,
> using the latest gcc. I never did get shared libs working the last time I
> build the cross compiler, and I would like to get it right this time.
>
> Thanks for any help.
>
> Jim
>
You should do the following on your host machine:
1. Decide where you want to put your cross compiler. Say under
/foo/bar, do
mkdir -p /foo/bar
2. Build cross assembler and binutils. You should get the latest
gas and binutils sources from ftp.cygnus.com under private/jelly.
You should get binutils 2.5.1 or later snapshot. Then just do
./configure --target=i486-linux --host=cpu-vendor-os --prefix=/foo/bar
make
make install
cp /foo/bar/bin
cp gcc gcc-ss
3. Get the current inc-x.y.z.tar.gz, image-x.y.z.tar.gz and
extra-x.y.z.tar.gz. Please do
cd /foo/bar
gzip -dc inc-x.y.z.tar.gz | tar xof -
gzip -dc image-x.y.z.tar.gz | tar xof - ./usr/lib
gzip -dc extra-x.y.z.tar.gz | tar xof -
cd usr
mv lib include ../i486-linux
cd ..
rm -rf usr
4. Get the current gcc sourcec code. Do
a. Build the gcc for your host machine. You can skip it if you
want to use the existing one installed on your system.
b. Build the cross compiler,
./configure --host=cpu-vendor-os --target=i486-linux --prefix=/foo/bar --local-prefix=/foo/bar
cat Makefile ../makefile.cross > makefile.cross
/foo/bar/i486-linux/bin/ar ucvr libgcc1.cross
make hlu -f makefile.cross
c. I never tried to do a
make install -f makefile.cross
You can install it by hand. That leaves as an exercise to
you. If you can not figure it yourself after reading the gcc
documentations, I think you should ask/pay someone to do it
for you.
H.J.
hjl@nynexst.com
10/14/94
------makefile.crosss----
OLDCC=./xgcc -V $(version) -B./ -b i486-linux -B$(tooldir)/bin/
OLDAR=$(AR)
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g1 \
$(LIBGCC2_T_CFLAGS)
LIBOBJC_CFLAGS=$(GCC_CFLAGS) -O2 -g1
STANDARD_STARTFILE_PREFIX=$(libsubdir)/
hlu: force
$(MAKE) CC=gcc-ss \
CFLAGS="-O -g" \
COMPILERS="cc1 cc1plus cc1obj" \
version=$(version) \
LANGUAGES="c c++ objc" CLIB= \
-f makefile.cross
-rm libgcc.a libgcc1.cross
$(MAKE) libgcc1.a libgcc1.cross libgcc.a \
CC=gcc-ss \
CFLAGS="-O -g" \
COMPILERS="cc1 cc1plus cc1obj" \
version=$(version) \
LANGUAGES="c c++ objc" CLIB= \
-f makefile.cross
------------------------------
From: neal@ctd.comsat.com (Neal Becker)
Subject: Stupid elf lib question
Date: 19 Oct 1994 13:33:30 GMT
I'm trying to understand the elf build environment. It seems the
linker looks for libs in /usr/i486-linuxelf/lib, while the dynamic
loader looks in /lib/elf.
Why two different paths?
------------------------------
End of GCC Digest
*****************
-------