Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

performance question #3097

Closed
vicuna opened this issue Dec 20, 2001 · 4 comments
Closed

performance question #3097

vicuna opened this issue Dec 20, 2001 · 4 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Dec 20, 2001

Original bug ID: 738
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

hi,

i have the following programm:

let time_func func =
begin
Printf.printf "start: %4.9f\n" (Unix.gettimeofday());
func () ;
Printf.printf "end: %4.9f\n" (Unix.gettimeofday())
end

let call_select times time =
let rec tues times =
if (times = 0)
then ()
else begin
ignore (Unix.select [] [] [] time);
tues (times - 1)
end
in
tues times

let _ =
time_func (function () -> call_select (int_of_string Sys.argv.(1))
(float_of_string Sys.argv.(2)))

   i do compile this on aix  and linux with
   ocamlopt -o messe  unix.cmxa mess1.ml


   then i get on aix:

time messe 1000 0.0
start: 1008862247.689975977
end: 1008862259.975527048

real 0m12.318s
user 0m5.350s
sys 0m0.070s

    and on linux

time messe 1000 0.0
start: 1008862258.931671977
end: 1008862259.318706036

real 0m0.406s
user 0m0.370s
sys 0m0.040s

    which is much faster,

M.Becker
@vicuna
Copy link
Author

vicuna commented Jan 4, 2002

Comment author: administrator

[Timing the Unix.select function]
i do compile this on aix and linux with
ocamlopt -o messe unix.cmxa mess1.ml
then i get on aix:
time messe 1000 0.0
start: 1008862247.689975977
end: 1008862259.975527048

real 0m12.318s
user 0m5.350s
sys 0m0.070s
and on linux

time messe 1000 0.0
start: 1008862258.931671977
end: 1008862259.318706036

real 0m0.406s
user 0m0.370s
sys 0m0.040s
which is much faster,

I don't think this speed difference has anything to do with OCaml.
Unix.select is a thin wrapper around the select() system call, and the
code is OS-independent. Chances are that if you rewrite your test in
C, you'll see the same speed difference. Some kernels are simply more
efficient (better algorithms and data structures) than others...

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Jan 7, 2002

Comment author: administrator

On Fri, 4 Jan 2002, Xavier Leroy wrote:

I don't think this speed difference has anything to do with OCaml.
Unix.select is a thin wrapper around the select() system call, and the
code is OS-independent. Chances are that if you rewrite your test in
C, you'll see the same speed difference.

i think the problem is the use of FD_SETSIZE in select
and in fdset_to_fdlist:

the value of FD_SETSIZE on aix is
/usr/include/sys/time.h: #define FD_SETSIZE 32767

so you run through the for-loop in fdset_to_fdlist  32767 times !

anyway, i did make some changes in select.c and my testprogramm
runs good

time mess 1000 0.001
start (pid=44244): 1010376716.065811992
end: 1010376717.095213056

real 0m1.036s
user 0m0.020s
sys 0m0.030s

but i did not test anything else!

-- m.becker


*** select.c Mon Jan 7 04:53:14 2002
--- o.select.c Mon Jan 7 04:38:55 2002


*** 33,63 ****

typedef fd_set file_descr_set;

! static int fdlist_to_fdset(value fdlist, file_descr_set *fdset)
{
! int maxi;
! int fdd;
!
! value l;
!
! FD_ZERO(fdset);
! maxi = 0;
!
for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
! fdd = Int_val(Field(l, 0)) ;
! maxi = fdd < maxi ? maxi : fdd ;
! FD_SET(fdd, fdset);
}

  • return maxi;
    }

! static value fdset_to_fdlist(file_descr_set *fdset, int maxi)
{
int i;
value res = Val_int(0);

Begin_root(res);

! for (i = maxi; i >= 0; i--) {
if (FD_ISSET(i, fdset)) {
value newres = alloc_small(2, 0);
Field(newres, 0) = Val_int(i);
--- 33,54 ----

typedef fd_set file_descr_set;

! static void fdlist_to_fdset(value fdlist, file_descr_set *fdset)
{
! value l;
! FD_ZERO(fdset);
for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
! FD_SET(Int_val(Field(l, 0)), fdset);
}
}

! static value fdset_to_fdlist(file_descr_set *fdset)
{
int i;
value res = Val_int(0);

Begin_root(res);

! for (i = FD_SETSIZE - 1; i >= 0; i--) {
if (FD_ISSET(i, fdset)) {
value newres = alloc_small(2, 0);
Field(newres, 0) = Val_int(i);


*** 71,78 ****

CAMLprim value unix_select(value readfds, value writefds, value exceptfds, value timeout)
{

  • int cc, maxi;
    
  • file_descr_set read, write, except;
    double tm;
    struct timeval tv;
    --- 62,67 ----

*** 82,96 ****
value read_list = Val_unit, write_list = Val_unit, except_list = Val_unit;

Begin_roots3 (read_list, write_list, except_list);

!
! maxi = fdlist_to_fdset(readfds, &read);
!
! cc = fdlist_to_fdset(writefds, &write);
! maxi = cc < maxi ? maxi : cc;
!
! cc = fdlist_to_fdset(exceptfds, &except);
! maxi = cc < maxi ? maxi : cc;
!
tm = Double_val(timeout);
if (tm < 0.0)
tvp = (struct timeval *) NULL;
--- 71,79 ----
value read_list = Val_unit, write_list = Val_unit, except_list = Val_unit;

Begin_roots3 (read_list, write_list, except_list);

! fdlist_to_fdset(readfds, &read);
! fdlist_to_fdset(writefds, &write);
! fdlist_to_fdset(exceptfds, &except);
tm = Double_val(timeout);
if (tm < 0.0)
tvp = (struct timeval *) NULL;


*** 100,111 ****
tvp = &tv;
}
enter_blocking_section();
! retcode = select(maxi + 1, &read, &write, &except, tvp);
leave_blocking_section();
if (retcode == -1) uerror("select", Nothing);
! read_list = fdset_to_fdlist(&read, maxi);
! write_list = fdset_to_fdlist(&write, maxi);
! except_list = fdset_to_fdlist(&except, maxi);
res = alloc_small(3, 0);
Field(res, 0) = read_list;
Field(res, 1) = write_list;
--- 83,94 ----
tvp = &tv;
}
enter_blocking_section();
! retcode = select(FD_SETSIZE, &read, &write, &except, tvp);
leave_blocking_section();
if (retcode == -1) uerror("select", Nothing);
! read_list = fdset_to_fdlist(&read);
! write_list = fdset_to_fdlist(&write);
! except_list = fdset_to_fdlist(&except);
res = alloc_small(3, 0);
Field(res, 0) = read_list;
Field(res, 1) = write_list;


@vicuna
Copy link
Author

vicuna commented Jan 11, 2002

Comment author: administrator

i think the problem is the use of FD_SETSIZE in select
and in fdset_to_fdlist:
the value of FD_SETSIZE on aix is
/usr/include/sys/time.h: #define FD_SETSIZE 32767
so you run through the for-loop in fdset_to_fdlist 32767 times !

OK, I overlooked this fact :-( Thanks for proving me wrong. I agree
a fix is in order, probably along the lines of what you sent me.

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented May 6, 2002

Comment author: administrator

Implemented more efficient building of return FD lists. XL, 2002-05-06

@vicuna vicuna closed this as completed May 6, 2002
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant