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

simple references sometimes slow #6003

Closed
vicuna opened this issue May 1, 2013 · 2 comments
Closed

simple references sometimes slow #6003

vicuna opened this issue May 1, 2013 · 2 comments
Assignees

Comments

@vicuna
Copy link

vicuna commented May 1, 2013

Original bug ID: 6003
Reporter: vbrankov
Assigned to: @gasche
Status: closed (set by @xavierleroy on 2015-12-11T18:18:49Z)
Resolution: not a bug
Priority: normal
Severity: minor
Category: back end (clambda to assembly)

Bug description

The following two code samples show inefficiency in dealing with references.

I believe that the first example is more likely to appear in a real world code. I have a feeling that it may not be hard to fix.

The second example is more synthetic. I understand the reason and I don't have a clear idea how it could be solved.

Steps to reproduce

let () =
let start = Unix.gettimeofday () in
let s = ref 0. in
for _i = 0 to 16_777_215 do
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.
done;
let _ = !s in
Printf.printf "%f\n" (Unix.gettimeofday () -. start);
let start = Unix.gettimeofday () in
let s = ref 0. in
for _i = 0 to 16_777_215 do
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.;
s := !s +. 1.
done;
let _ = !s +. 1. in
Printf.printf "%f\n" (Unix.gettimeofday () -. start)

let foo x =
let _ = !x in ()

let () =
let start = Unix.gettimeofday () in
let s = ref 0 in
for _i = 0 to 16_777_215 do
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1
done;
foo s;
Printf.printf "%f\n" (Unix.gettimeofday () -. start);
let start = Unix.gettimeofday () in
let s = ref 0 in
for _i = 0 to 16_777_215 do
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1;
s := !s + 1
done;
foo (ref (!s + 1));
Printf.printf "%f\n" (Unix.gettimeofday () -. start)

@vicuna
Copy link
Author

vicuna commented May 1, 2013

Comment author: @gasche

There is no bug here.

The int behavior is the expect result of the local reference unboxing strategy: the call to the external function foo makes the reference escape, so it is kept in its boxed form, while the second loop doesn't escape "s", so a local mutable variable is used instead. Let's not get roles confused here: it is not the first code that is too slow, but the second one that is faster than expected! Of course, this optimization is local in scope and is expected to stop applying at some point.

The float behavior is a bit less satisfying because as you notice the "escape analysis" is in this case a bit more fragile. This is known, and Alain Frisch and Pierre Chambart have been working on better unboxing strategies (see e.g. Alain Frisch "more_unboxing" SVN branch).

I appreciate the time and interest you devote in micro-optimizations of the compiler, but I will still close this bug report as there is no real-world code being improved here.

@vicuna
Copy link
Author

vicuna commented May 1, 2013

Comment author: vbrankov

Thank you very much for the quick response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants