]> git.cworth.org Git - cworth.org/blob - src/exa/i965/synchronous_composite.mdwn
Convert prefix directives to new syntax.
[cworth.org] / src / exa / i965 / synchronous_composite.mdwn
1 [[!meta title="Synchronous compositing in the i965 driver"]]
2
3 [[!tag exa performance xorg]]
4
5 A couple of weeks ago I aired [[my_confusion|avoiding_rmw]] about a
6 situation in which using EXA with an i965 card was 4 times slower than
7 using NoAccel, but that there weren't any large bottlenecks visible in
8 the profile at all, (nothing over 5%). And that didn't seem likely at all.
9
10 As is [often the
11 case](http://en.wikipedia.org/wiki/The_Answer_to_Life,_the_Universe,_and_Everything)
12 this wasn't a wrong answer, but was instead a problem with me not
13 understanding the question I had asked. I had been profiling over
14 enttire runs of mozilla's Trender benchmark, but the 4x slowdown was
15 based on the results it reported which measured only the inner loop of
16 rendering itself. So my profiles including extraneous computation such
17 as page loading that Trender was explicitly not measuring. This was
18 actually easy to determine by simply measuring the total runtime of
19 Trender and seeing that it slowed down by only 1.5x instead of 4x.
20
21 So to get better profiling data, I changed strategy slightly and
22 started using an [[on-demand_Trender_technique|trender_bookmark]] that
23 Vladimir offered me. It makes it easy to run a one-off Trender loop
24 for hundreds of iterations so I can profile exactly the rendering and
25 nothing else.
26
27 So I used that approach to measure the rendering performance of a
28 [worthwhile web page](http://www.gnu.org/licenses/gpl-3.0.html), with
29 both NoAccel and EXA, (again with an Intel i965 card). I used my
30 standard [profile script](http://cworth.org/bin/profile) to generate
31 piles of data.
32
33 The trickiest part was then coming up with a reasonable way to
34 visualize the data to try to figure out what was going on. My brother,
35 [[Richard]], pulled his usual HTML+CSS magic and came up with the
36 following for me.
37
38         Note: If you click through to my blog, you'll get to see these charts
39         in their colorful glory. Otherwise, if you're reading this
40         somewhere like http://planet.gnome.org then you'll probably
41         just see the boring list version. But one really cool thing
42         about Richard's hack here is that in the absence of CSS
43         styling this chart does degrade nicely to just list with all the data
44         available. So these charts should be much more accessible than things
45         I've done previously with PNG bar chart images. Plus, I get to
46         embed hyperlinks at all the intuitive spots as well. Anyway, Richard
47         totally rocks for having put this together.
48
49 <dl class="chart barchart">
50     <dt>NoAccel (<a href="http://cworth.org/exa/i965/synchronous_composite/NoAccel/timing">14 ms.</a>) <a href="http://cworth.org/exa/i965/synchronous_composite/NoAccel/system.oprofile">system profile</a> <a href="http://cworth.org/exa/i965/synchronous_composite/NoAccel/system.symbols">symbols profile</a></dt>
51     <dd style="width:18%;">
52         <ul>
53             <li class="pixman" style="width:42%;"><a href="http://cworth.org/exa/i965/synchronous_composite/NoAccel/pixman.oprofile">pixman</a> <span>42%</span></li>
54             <li class="libxul" style="width:16%;">libxul <span>16%</span></li>
55             <li class="vmlinux" style="width:16%;">vmlinux <span>16%</span></li>
56             <li class="Xorg" style="width:7%;"><a href="http://cworth.org/exa/i965/synchronous_composite/NoAccel/X.oprofile">Xorg</a> <span>7%</span></li>
57             <li class="libc" style="width:5%;"><a href="http://cworth.org/exa/i965/synchronous_composite/NoAccel/libc.oprofile">libc</a> <span>5%</span></li>
58             <li class="other" style="width:14%">other <span>14%</span></li>
59         </ul>
60     </dd>
61     <dt>EXA (<a href="http://cworth.org/exa/i965/synchronous_composite/EXA/timing">77 ms.</a>) <a href="http://cworth.org/exa/i965/synchronous_composite/EXA/system.oprofile">system profile</a> <a href="http://cworth.org/exa/i965/synchronous_composite/EXA/system.symbols">symbols profile</a></dt>
62     <dd style="width:100%;">
63         <ul>
64             <li class="libc" style="width:30%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA/libc.oprofile">libc</a> <span>30%</span></li>
65             <li class="intel_drv" style="width:19%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA/intel_drv.oprofile">intel_drv</a> <span>19%</span></li>
66             <li class="vmlinux" style="width:16%;">vmlinux <span>16%</span></li>
67             <li class="libxul" style="width:11%;">libxul <span>11%</span></li>
68             <li class="libexa" style="width:6%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA/libexa.oprofile">libexa</a> <span>6%</span></li>
69             <li class="pixman" style="width:5%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA/pixman.oprofile">pixman </a><span>5%</span></li>
70             <li class="Xorg" style="width:4%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA/X.oprofile">Xorg</a> <span>4%</span></li>
71             <li class="other" style="width:9%">other <span>9%</span></li>
72         </ul>
73     </dd>
74 </dl>
75
76 So there are some big percentages there---much nicer than the little
77 4% and 5% things I was seeing a couple of weeks ago. So, yes, it
78 definitely helps to know that you're asking the question you mean to
79 be. There are several links in the chart above to different profile
80 reports. If you drill down the libc profile, you'll see that there's a
81 lot of memcpy going on.
82
83 An easy guess is that the memcpy is due to pixmap migration due to
84 software fallbacks. To verify this guess, I first disabled all pixmap
85 migration from video memory to system memory, (which was as simple as
86 `if (! can_accel) return;` in `exaDoMigration`. This actually got rid of
87 most of the memcpy problem, and didn't cause any incorrect
88 rendering. Next I enabled `DEBUG_TRACE_FALL` in `exa_priv.h` to
89 identify all fallbacks that were getting hit by the benchmark and I
90 put early returns in place to disable them. Unsuprisingly, this did
91 cause a lot of incorrect rendering.
92
93 And of course, what we really want to do is to find what is triggering
94 those fallbacks and accelerate them. But for now, I wanted to see how
95 performance would be if we were already at the point that we had no
96 software fallbacks at all. Here's what I got:
97
98 <dl class="chart barchart">
99     <dt>EXA-no-fallbacks (<a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/timing">58 ms.</a>) <a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/system.oprofile">system profile</a> <a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/system.symbols">symbols profile</a></dt>
100     <dd style="width:75%;">
101         <ul>
102             <li class="vmlinux" style="width:23%;">vmlinux <span>23%</span></li>
103             <li class="intel_drv" style="width:22%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/intel_drv.oprofile">intel_drv </a><span>22%</span></li>
104             <li class="libc" style="width:16%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/libc.oprofile">libc </a><span>16%</span></li>
105             <li class="libxul" style="width:13%;">libxul <span>13%</span></li>
106             <li class="pixman" style="width:9%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/pixman.oprofile">pixman </a><span>9%</span></li>
107             <li class="libexa" style="width:4%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/libexa.oprofile">libexa </a><span>4%</span></li>
108             <li class="Xorg" style="width:4%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-fallbacks/X.oprofile">Xorg </a><span>4%</span></li>
109             <li class="other" style="width:9%">other <span>9%</span></li>
110         </ul>
111     </dd>
112 </dl>
113
114 <br>So, as hoped, a lot of the libc time went away. But there's still
115 a heck of a lot left, as well as kernel system-call time. That's
116 clearly in gettimeofday and that's easy to track down to the
117 `I830WaitLpRing` function. Fortunately, it's also extremely easy to
118 eliminate that system call almost entirely there. The only reason it's
119 being called is to ensure that we don't busy-wait forever, (due to a
120 video card lockup). So we could call gettimeofday only once every
121 several thousand iterations and still detect lockup very
122 quickly. Here's a
123 [[patch|0001-Elminate-gettimeofday-as-a-hotspot-in-I830WaitLpRing.patch]]
124 to do exactly that.
125
126 So, now take a look at the performance with this patch attached:
127
128 <dl class="chart barchart">
129     <dt>EXA-no-gettimeofday (<a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/timing">54 ms.</a>) <a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/system.oprofile">system profile</a> <a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/system.symbols">symbols profile</a></dt>
130     <dd style="width:70%;">
131         <ul>
132             <li class="intel_drv" style="width:49%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/intel_drv.oprofile">intel_drv </a><span>49%</span></li>
133             <li class="libxul" style="width:16%;">libxul <span>16%</span></li>
134             <li class="libc" style="width:10%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/libc.oprofile">libc </a><span>10%</span></li>
135             <li class="pixman" style="width:7%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/pixman.oprofile">pixman </a><span>7%</span></li>
136             <li class="libexa" style="width:4%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/libexa.oprofile">libexa </a><span>4%</span></li>
137             <li class="Xorg" style="width:2%;"><a href="http://cworth.org/exa/i965/synchronous_composite/EXA-no-gettimeofday/X.oprofile">Xorg </a><span>2%</span></li>
138             <li class="vmlinux" style="width:2%;">vmlinux <span>2%</span></li>
139             <li class="other" style="width:10%">other <span>10%</span></li>
140         </ul>
141     </dd>
142 </dl>
143
144 <br>Again, a lot of the libc time was eliminated, and a _huge_ amount
145 of the kernel time was eliminated as well. But, sadly, and
146 dramatically, the overall performance did not improve much at all. The
147 time spent in the Intel driver increased not only in percentage, but
148 also increased in absolute timing, taking up almost all of the time
149 saved from libc and the kernel.
150
151 What's going on here? What's happening is that the driver is spending
152 an awful lot of time busy-waiting, and all we did here was to help it
153 busy-wait even faster. Now, we know that there aren't any software
154 fallbacks happening here, so what's all the waiting about? It appears
155 to be caused primarily by `i965_prepare_composite` which includes the
156 following comment and code:
157
158     /* Because we only have a single static buffer for our state currently,
159      * we have to sync before updating it every time.
160      */
161     i830WaitSync(pScrn);
162
163 That is, when we want to render multiple composite operations in
164 sequence, instead of doing some nice, pipelined fire-and-forget
165 operations, the driver is currently waiting for the previous composite
166 operation to entirely complete before starting off another. _And_ it's
167 doing that waiting with CPU-burning busy-waiting.
168
169 I'll need to learn a bit more about this hardware before I can know
170 the right way to fix this, (my, but documentation would certainly be
171 helpful about now). For example, it would be easy to setup a circular
172 buffer of state structures. But can I get the hardware to tell me when
173 composite operations complete so that I can efficiently reuse those?
174 Another approach would be to stuff the necessary compositing state
175 into the LP ring the same way the compositing commands are being
176 sent. Is there any reason not to do that?
177
178 Meanwhile, it looks like there's a bunch of state in the strucure that
179 needn't be sent every time, (much of it is always constant). So there
180 are likely easy ways to improve that as well. I'm definitely looking
181 forward to people with more Intel-hardware-specific knowledge helping
182 me out here, (or just plain fixing the thing).
183
184 Meanwhile, even if the driver time were completely eliminated, the
185 rest of the time in this profile would still exceed what was spent in
186 the NoAccel case. Some things are plainly working well, such as the
187 fact that the pixman time has gone down. Some things are not working
188 well, such as the new time being spent in libexa, (which appears to be
189 mostly an inefficient approach for computing an LRU heuristic as I
190 mentioned earlier). Some of the increased time, such as that of libc,
191 might be related to driver problems that we hope to fix.
192
193 But one item in particular looks very strange. The libxul code is
194 spending signficantly more time in the EXA case than in the NoAccel
195 case, when we wouldn't expect it to be aware of the difference at
196 all. That will be an interesting thing to track down, (and it sure
197 would be nice if that were the biggest thing to worry about right
198 now). But clearly we've got a lot of work to do to get the i965
199 performing properly with EXA.