[Ilugc] .a-tip-a-day (patch - apply diffs and act as inverse of diff)

  • From: mbhangui@xxxxxxxxx (Manvendra Bhangui)
  • Date: Wed Sep 30 20:51:24 2009

On Wed, Sep 30, 2009 at 6:01 PM, Kapil Hari Paranjape <kapil@xxxxxxxxxxx>wrote:


While your intentions were honourable, your remark was about speed
and efficiency and number of syscalls --- none of which has anything
to do with reading/writing C!


It does have. The flexibility of writing in C is that I can further reduce
the syscalls. It gives me so many ways to manipulate my environment. On a
server like a mail server which is processing few million mails a day,
choice between using spamassasin written in perl or using something like
bogofilter in C makes as much difference as to reduce the number of servers
by half. In troubled economic times, each syscall counts and I cannot
explain the relief and the pride one feels when one sees on the top screen
(/usr/bin/top), to see the load dropping, the moment you engineer something
like this.

Even in python and perl, you can generate a compiled code. Apart from saving
on the parsing, I am not sure how much one can save. I used to do that with
tcl/tk

Coming back to the example

Instead of writing
#include <stdio.h>
int
main()
{
printf("hello world\n");
}
gcc try.c -o try
The above try when executed will execute 24 system calls

But I can write my program without any main() and the entry is through
_start()

#include <sys/syscalls.h>
int
_start()
{
syscall(SYS_write, 1, "hello world\n", 12);
}
gcc  -nostartfiles -nodefaultlibs try.c -o try -lc

I save two system calls. One of them is a stupid call by printf() to check
if file descriptor 1 is a
character device

fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xb7f0b000

The 22 syscalls are below after all the optimization is below and if you see
only the 2nd last line is the one which actually does the job of putting the
string "hello world" on the screen.

brk(0)                                  = 0x9783000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or
directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=152155, ...}) = 0
mmap2(NULL, 152155, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fc5000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3,
"\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\v\\\0004\0\0\0\354"...,
512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1803428, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xb7fc4000
mmap2(0x5aa000, 1509672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3,
0) = 0x5aa000
mmap2(0x715000, 12288, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16b) = 0x
mmap2(0x718000, 10536, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x718
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xb7fc3000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7fc36c0, limit:1048575,
seg_32bit:1, content
mprotect(0x715000, 8192, PROT_READ)     = 0
mprotect(0x5a6000, 4096, PROT_READ)     = 0
munmap(0xb7fc5000, 152155)              = 0
write(1, "hello world\n"..., 12)        = 12
exit_group(12)                          = ?

In the above example where both the programs were written in C if the code
gets executed million times, I will save 2 million of system calls. However
the above example is not the right example for all situation. Example it is
better to call printf rather than syscall(SYS_write) if you are going to
call printf multiple times.

Other related posts: