weixin_39654917
weixin_39654917
2020-12-02 12:52

Slight sidebar flicker on MS Windows

I have today seen the current nightly build on MS Windows showing slight sidebar flicker. I don't know if it was synchronous to the cursor blinking and I don't know if that is a problem of the graphics driver or similar. But as the Greek sidebar, the history sidebar and the Table of contents sidebar were affected and flicker can point to spurious redraws I wanted to report that.

该提问来源于开源项目:wxMaxima-developers/wxmaxima

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

12条回答

  • weixin_39986171 weixin_39986171 5月前

    It depends on what compiler options you choose, not on the platform - and since we just use cmake defaults, the situation is comparable on any platform. The debug build's hot paths can be several times slower, since e.g. the C++ library and wxWidgets do index range checking, the compiler doesn't inline functions, and generally the process gives the compiler a leisurely time. The release builds, first of all, take longer. They have to. The compiler has way more work to do with them. That's how you can easily tell release from debug builds, although on mingw the crappy gnu linker may skew the results.

    For me, the release builds are really smooth, whereas the debug builds are a bit jerky here and there in terms of scrolling etc. When things were slow and some access patterns magnified the slowness, the debug build's document loading time was 10x longer than release build's.

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    The cache pressure has significant performance impact: since I began the slimming, the Cell went from ~340 bytes down to ~140, and TextCell went down from ~900 to ~420, and ideally we want the Cell to be ~32-64 bytes, and a TextCell <128 for short strings. This has very noticeable effects on interactive performance. Ideally I'd want a small TextCell (like parentheses) to be <=64 bytes, maybe less. It all depends on how much effort is put into it. But once a screen's worth of Cell data can fit mostly into L1 cache, the layout code's impact from our end will essentially vanish, and we'll be at a point where e.g. parallelizing text chunk sizing will make sense - and no earlier.

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    There's another problem: because of the incredibly convoluted way we handle size recalculation, the process is not incremental, i.e. it doesn't progress "ahead" only. Depending on timing, it gets repeated, often multiple times, or some parts of it don't get done at all before the stale data is used. Ideally, the layout process would be completely deterministic and user's actions in the UI (scrolling etc) would only insert pauses into it at various times, but the overall process itself would do exactly the same steps, and do them once.

    The whole category of "timing" bugs we have are not somehow unavoidable: they stem from the ad-hoc and non-deterministic nature of the cell layout process. At some point those bugs simply must stop happening, so that's some near goal .

    But for now, the outcome of the speed-ups is that various bugs are now triggered by repaints that never had a chance to occur. So we're getting crashes and all sorts of ugly recalculation code comes into focus.

    点赞 评论 复制链接分享
  • weixin_39654917 weixin_39654917 5月前

    Borrowed a Windows Computer today. wxMaxima is very fast after all your improvements. But fhe flicker of the sidebars is still there. But why?

    With anything we do in the worksheet the flicker of the sidebars should not have anything to do: They are entirely different GUI elements

    As far as I know layouting maths is a process that cannot reduced to a single pass:

    • First we layout all cells
    • Only then we can determine which elements are wider than one page and therefore have to be displayed in linear, not in 2D form in order to fit on the screen.
    • The linear form can use different font sizes than the 2D form. For example exponents in 2D form are displayed smaller than they are in linear form. This that the cells we have just converted to linear form have to be recalculated - at least if breaking them into lines has changed their font size.

    What I am not sure about is if we really have to split recalculation into a RecalculateHeight() and RecalculateWidths() for some cells, though. Also we could speed up things a little if we used the 2nd recalculation step for determining where to place soft linebreaks, as that would reduce the number of times we iterate through the m_mextToDraw lists.

    If the debug build contains many additional checks I am not unhappy with that: It is always good to be warned about bugs as soon as possible. But if that massively reduces speed I maybe have made a wrong decision when I told to use a debug build for compiling the maxima+wxMaxima installer. On the other hand including debug symbols in the release often greatly helps when trying to debug errors that only happen on this one specific system => now I am unsure what settings we should use for the release... ...and on appVeyor: Since we don't run the program there creating a debug build doesn't help at all, tight?

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    It is still a linear single pass process: you lay out 2d until there’s a need to break the line, and then you may restart the layout using a different output format, but there’s a fixed sequence of steps, and it always happens the same for a given initial conditions: once the 2d layout is too wide, it repeats in an alternate layout. There’s never a case that a part of it would be skipped or done out of order, or some extra steps inserted. Currently, when I output traces of various recalculate methods, we get many different sequences based on repaint timing, and that causes all sorts of trouble.

    After we’ll make and use cell iterators in the layout process, and clean up the layout methods of Cell, the layout can be done using a C++ standard library algorithm, and then if we detect C++20 on Windows it can be parallelized without doing anything special - just by providing an execution policy to the algorithm. There we can do text sizing on all cores in parallel.

    On X11, as long as client-side text rendering is used with freetype + harfbuzz, rather than letting the server draw text, we can parallelize that as well (with some caveats - I’ve last done it long ago).

    17 juli 2020 kl. 6:42 fm skrev Gunter Königsman :

     Borrowed a Windows Computer today. wxMaxima is very fast after all your improvements. But fhe flicker of the sidebars is still there. But why?

    With anything we do in the worksheet the flicker of the sidebars should not have anything to do: They are entirely different GUI elements

    As far as I know layouting maths is a process that cannot reduced to a single pass:

    First we layout all cells Only then we can determine which elements are wider than one page and therefore have to be displayed in linear, not in 2D form in order to fit on the screen. The linear form can use different font sizes than the 2D form. For example exponents in 2D form are displayed smaller than they are in linear form. This that the cells we have just converted to linear form have to be recalculated - at least if breaking them into lines has changed their font size. What I am not sure about is if we really have to split recalculation into a RecalculateHeight() and RecalculateWidths() for some cells, though. Also we could speed up things a little if we used the 2nd recalculation step for determining where to place soft linebreaks, as that would reduce the number of times we iterate through the m_mextToDraw lists.

    If the debug build contains many additional checks I am not unhappy with that: It is always good to be warned about bugs as soon as possible. But if that massively reduces speed I maybe have made a wrong decision when I told to use a debug build for compiling the maxima+wxMaxima installer. On the other hand including debug symbols in the release often greatly helps when trying to debug errors that only happen on this one specific system => now I am unsure what settings we should use for the release... ...and on appVeyor: Since we don't run the program there creating a debug build doesn't help at all, tight?

    — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

    点赞 评论 复制链接分享
  • weixin_39654917 weixin_39654917 5月前

    The first paragraph more or less describes what we try to do:

    • First all cells are layouted
    • If we see that one of these cells is wider than the screen we change it to the linear format that can be broken into lines: For example fractions that normally contain of a numerator and a denominator divided by a horizontal line are converted into the three cells "numerator", "/" and "denominator". The first problem is now that the numerator and denominator inside a 2d fraction are displayed in a smaller font than they are in the linear form. The second problem is that we know that numerator and denominator both might be 2D objects that might be wider than the screen and therefore might need to be converted to linear form, too. And the objects these objects are composed of might still be too wide and therefore might again need to be converted to their linear form before we can introduce the linebreaks.

    If we don't recalculate a cell at all that clearly looks like being a bug, though - and I believe that wxMaxima splitting recalculation into recalculating heights and then recalculating widths makes things more complicated [and therefore error-prone] than necessary and at the same time introduces avoidable traversals through lists. Also some cells instead of heights recalculate widths or don't do anything during height calculation and then correct everything during the width calculation => If you haven't starting optimizing this process yet I am willing to try to merge RecalculateHeight and RecalculateWidth of each cell type to a single Recalculate function.

    Paralleling things is great. But wxDC::GetTextExtend isn't thread save which means we'd have introduce an awful lot of locking. Also if we want to avoid introducing more threads than we have CPUs at hand if we drop OpenMP we'd have to set up our own task queue management and be careful that this doesn't introduce more overhead than it reduces the calculation time.

    But I agree with you: As soon as all relevant compiler versions support instantiating tasks without having to resort to OpenMP we should drop OpenMP.

    Parallelizing the output would be fast - and I don't know how much work one could delegate to the GPU, if one starts to optimize the output. But once we stop using only standard wxWidgets methods the standard way it is us who have to manually support all versions of all operating systems including things like an ubuntu version shipping a broken gnome2, a debian version insisting of shipping an old wxWidgets with experimental gnome3 support while entirely dropping gnome2, a nearly-linux compatible OpenBSD, Wayland, X11, perhaps even MIR and a quirky xvfb. We can do many wonders in places that provide a better improvement in performance per working hour we need to invest.

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    GetTextExtent’s underlying platform API is thread safe on Windows, and it probably is as well on X11 since at least xcb and probably also libx11 allows multithreaded access to the server and locks everything as needed. If that’s not the case then it’s easy to fix. The x11 APIs already have a lock, but if it ends up being done on the client then we can call the text sizing APIs like harfbuzz ourselves, and that’s thread safe too. So in the long run it’ll be OK, but not now.

    Rendering using the GPU lets the fragment shader compute the actual outline of the font using a special distance map representation, so that’s almost absurdly fast and allows zooming with no CPU involvement.

    But that will come later. For now, in a document with many parentheses we size the same parentheses thousands of times, and just avoiding that would help. We need not only a font cache, but also a text size cache - and that will need special effort, since a “simple” string-indexed map or hash will be the maybe last thing we want. But I have something in mind, so that we won’t need to store any string sizes in TextCell, and for that matter we also won’t need to store any strings either.

    But more broadly, the improvements we can make probably belong in wxWidgets themselves, and I’ll have to get myself to start pushing some code there.

    18 juli 2020 kl. 11:59 fm skrev Gunter Königsman :

     The first paragraph more or less describes what we try to do:

    First all cells are layouted If we see that one of these cells is wider than the screen we change it to the linear format that can be broken into lines: For example fractions that normally contain of a numerator and a denominator divided by a horizontal line are converted into the three cells "numerator", "/" and "denominator". The first problem is now that the numerator and denominator inside a 2d fraction are displayed in a smaller font than they are in the linear form. The second problem is that we know that numerator and denominator both might be 2D objects that might be wider than the screen and therefore might need to be converted to linear form, too. And the objects these objects are composed of might still be too wide and therefore might again need to be converted to their linear form before we can introduce the linebreaks. If we don't recalculate a cell at all that clearly looks like being a bug, though - and I believe that wxMaxima splitting recalculation into recalculating heights and then recalculating widths makes things more complicated [and therefore error-prone] than necessary and at the same time introduces avoidable traversals through lists. Also some cells instead of heights recalculate widths or don't do anything during height calculation and then correct everything during the width calculation => If you haven't starting optimizing this process yet I am willing to try to merge RecalculateHeight and RecalculateWidth of each cell type to a single Recalculate function.

    Paralleling things is great. But wxDC::GetTextExtend isn't thread save which means we'd have introduce an awful lot of locking. Also if we want to avoid introducing more threads than we have CPUs at hand if we drop OpenMP we'd have to set up our own task queue management and be careful that this doesn't introduce more overhead than it reduces the calculation time.

    But I agree with you: As soon as all relevant compiler versions support instantiating tasks without having to resort to OpenMP we should drop OpenMP.

    Parallelizing the output would be fast - and I don't know how much work one could delegate to the GPU, if one starts to optimize the output. But once we stop using only standard wxWidgets methods the standard way it is us who have to manually support all versions of all operating systems including things like an ubuntu version shipping a broken gnome2, a debian version insisting of shipping an old wxWidgets with experimental gnome3 support while entirely dropping gnome2, a nearly-linux compatible OpenBSD, Wayland, X11, perhaps even MIR and a quirky xvfb. We can do many wonders in places that provide a better improvement in performance per working hour we need to invest.

    — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

    点赞 评论 复制链接分享
  • weixin_39654917 weixin_39654917 5月前

    Improving wxWidgets would be a great idea as that would improve many projects in one go. But afaics the flicker is gone => closing this issue.

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    I've seen that too, yes. Nothing to do with graphics drivers, everything to do with the absurdly bad way wxWidgets handles control updates. It's not even a Windows issue - it's just that wxWidgets is bad. Given that it is supposed to run on smaller legacy systems, I'm amazed at how much memory and CPU cycles it wastes.

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    Your improvements in recent commits have definitely improved the responsiveness of the interface. On my computer, with debug builds, wxMaxima can leap slightly ahead of Maxima and there are some History and similar updates - meaning that the event loop gets idle waiting for communications. Debug builds were absurdly slow just a month ago - unusable, making debugging a chore.

    On my end, I've shrunk the memory used up by cells in a TextCell-heavy cell output mix by half. The base Cell class is almost 1/3 its original size.

    点赞 评论 复制链接分享
  • weixin_39986171 weixin_39986171 5月前

    Wow. The Windows release build is now faster than Maxima can feed it with data, i.e. it can completely keep up. It's quite awesome! Even the debug build is getting there. Ideally, I'd like not to see much speed difference in the debug builds - a very much achievable goal.

    点赞 评论 复制链接分享
  • weixin_39654917 weixin_39654917 5月前

    What surprises me is that wxMaxima now has grown so fast that even things that a few months ago were small improvements are now visible.

    I wonder now: On linux I am convinced that the debug build mainly differs from the Real Thing by being bundled with a list of debug symbols. Is this this different on windows?

    点赞 评论 复制链接分享

相关推荐