Winit: Window much slower to spawn with external monitor connected

Created on 22 Oct 2018  Â·  10Comments  Â·  Source: rust-windowing/winit

I'm continuing down a rabbit hole that started in jwilm/alacritty#1603 and continued in tomaka/glutin#1070. Specifically, it looks like my terminal (alacritty), which uses glutin, which uses init, is much slower to spawn its initial window in certain cases. In particular, on my laptop (a 6th generation Lenovo X1 Carbon, so new hardware), there is a marked difference in the time it takes to spawn a single winit window depending on whether an external monitor is connected or not.

In particular, running the following code with --release:

extern crate winit;
fn main() {
    let mut events_loop = winit::EventsLoop::new();
    let _window = winit::WindowBuilder::new()
        .with_title("A fantastic window!")
        .build(&events_loop)
        .unwrap();
    events_loop.run_forever(|_| winit::ControlFlow::Break);
}

Without an external monitor connected:

0.01user 0.00system 0:00.14elapsed 14%CPU (0avgtext+0avgdata 6312maxresident)k
0inputs+0outputs (0major+544minor)pagefaults 0swaps

With an external monitor connected:

0.01user 0.00system 0:00.48elapsed 4%CPU (0avgtext+0avgdata 6340maxresident)k
0inputs+0outputs (0major+533minor)pagefaults 0swaps

That's 0.14s to 0.48s on the same system with a different monitor configuration, which seems surprising.

I took some perf profiles, though there's relatively little fidelity since I just spawn and immediately close a window. Without external monitor:
perf without external monitor
With external monitor:
perf with external monitor

The relevant lines from xrandr -q in the two configurations are:

Screen 0: minimum 320 x 200, current 2560 x 1440, maximum 8192 x 8192
eDP-1 connected 2560x1440+0+0 (normal left inverted right x axis y axis) 309mm x 174mm
   2560x1440     60.01*+  59.99    59.99    59.96    59.95

and

Screen 0: minimum 320 x 200, current 3120 x 1920, maximum 8192 x 8192
eDP-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 309mm x 174mm
   1920x1080     60.01    59.97    59.96*   59.93
HDMI-1 connected primary 1200x1920+1920+0 left (normal left inverted right x axis y axis) 546mm x 352mm
   1920x1200     59.95*+
   1920x1080     60.00    50.00    59.94    59.99
X11 help wanted needs investigation bug

Most helpful comment

There seem to be multiple issues floating around related to this. For me, it causes Alacritty opening twice sometimes using an i3 keybind. (https://github.com/jwilm/alacritty/issues/1859)

In a previous Alacritty version, we could explicitly disable calling into xrandr to detect the current screen's DPI. Initially, I though winit was shelling out to xrandr, but the flame graph shows a call into libX11; seems that call is also very slow. Setting WINIT_HIDPI_FACTOR does not seem to prevent the xrandr call.

The more screens/adapters a machine has, the longer this call seems to take. My experience with this behaviour seems consistent on different versions across different machines. The codebase also seems to be aware of this: https://github.com/tomaka/winit/blob/master/src/platform/linux/x11/monitor.rs#L134.

➜  ~  time alacritty -e true

alacritty -e true  0.08s user 0.02s system 22% cpu 0.471 total
➜  ~  time xrandr >/dev/null

xrandr > /dev/null  0.01s user 0.00s system 1% cpu 0.348 total

Hope this comment was helpful, might give the hunt for the cause a new spin. :slightly_smiling_face:

All 10 comments

/cc @francesca64

Sorry for the wait! Since I can't reproduce this, and I don't see anything notable in the flame graph, fixing this could be tricky.

To start bisecting this, I've made a branch that doesn't query the monitors at all: https://github.com/francesca64/winit/tree/x11-dummy-monitor. If you try running that, is the speed consistent?

Yup, opening time is completely consistent on that branch:

$ time target/release/examples/open
0.01user 0.00system 0:00.02elapsed 86%CPU (0avgtext+0avgdata 6276maxresident)k
0inputs+0outputs (0major+540minor)pagefaults 0swaps

I have the same problem with alacritty (2.3). 300ms on the laptop. 600ms when external monitor is connected. With @francesca64 dummy monitor hack, alacritty starts in 120ms. Of course it will probably mess up any HIDPI detection. But I am lucky to have a very similar DPI between my laptop and external monitor.

There seem to be multiple issues floating around related to this. For me, it causes Alacritty opening twice sometimes using an i3 keybind. (https://github.com/jwilm/alacritty/issues/1859)

In a previous Alacritty version, we could explicitly disable calling into xrandr to detect the current screen's DPI. Initially, I though winit was shelling out to xrandr, but the flame graph shows a call into libX11; seems that call is also very slow. Setting WINIT_HIDPI_FACTOR does not seem to prevent the xrandr call.

The more screens/adapters a machine has, the longer this call seems to take. My experience with this behaviour seems consistent on different versions across different machines. The codebase also seems to be aware of this: https://github.com/tomaka/winit/blob/master/src/platform/linux/x11/monitor.rs#L134.

➜  ~  time alacritty -e true

alacritty -e true  0.08s user 0.02s system 22% cpu 0.471 total
➜  ~  time xrandr >/dev/null

xrandr > /dev/null  0.01s user 0.00s system 1% cpu 0.348 total

Hope this comment was helpful, might give the hunt for the cause a new spin. :slightly_smiling_face:

When available, we should consider using XRRGetScreenResourcesCurrent instead, which is a couple orders of magnitude faster according to this issue: https://github.com/glfw/glfw/issues/347

To quote:

XRRGetScreenResourcesCurrent: Tipically from 20 to 100 us.
XRRGetScreenResources: Typically from 13600 to 13700 us.

Hey fellas, take this for a spin: https://github.com/tomaka/winit/pull/801

Hmm, I've recently switched out my screen for a non-rotated one, and can no longer produce the increased delay with an external monitor attached sadly :/

Closing this, since #801 was merged and that largely seems to have solved this. Please feel free to re-open this if that's an inaccurate assessment

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chrisduerr picture chrisduerr  Â·  3Comments

dhardy picture dhardy  Â·  3Comments

rukai picture rukai  Â·  4Comments

chrisduerr picture chrisduerr  Â·  4Comments

mistodon picture mistodon  Â·  4Comments