wxDC Performance OSX (CPU Hog)
-
- Earned a small fee
- Posts: 12
- Joined: Thu Mar 26, 2009 9:03 pm
wxDC Performance OSX (CPU Hog)
Hello all,
In my application I use a large panel with a wxDC to draw on. I refresh the screen every 50ms to render about 20fps. On windows (retina, emulated with parallels desktop) this application consumes about 7% CPU. In the OSX version (MacBook Pro 2017 TouchBar, running High Sierra), the CPU load is 109%. I tested the various render loops samples described here: https://wiki.wxwidgets.org/Making_a_render_loop, but they all become a CPU hog when de canvas is dragged bigger. Is there another option I've missed out? Do other users experience the same drastic performance difference?
Thanks in advance,
Bart
In my application I use a large panel with a wxDC to draw on. I refresh the screen every 50ms to render about 20fps. On windows (retina, emulated with parallels desktop) this application consumes about 7% CPU. In the OSX version (MacBook Pro 2017 TouchBar, running High Sierra), the CPU load is 109%. I tested the various render loops samples described here: https://wiki.wxwidgets.org/Making_a_render_loop, but they all become a CPU hog when de canvas is dragged bigger. Is there another option I've missed out? Do other users experience the same drastic performance difference?
Thanks in advance,
Bart
Re: wxDC Performance OSX (CPU Hog)
Disclaimer: I don't use OSX and can't test this.
Which wxWidgets version are you using?
I've never read about a similar problem, so i don't think there is a general problem. Can you profile the code and identify any hot spots?
If not, try commenting out parts of the drawing code, maybe you can isolate one particular operation responsible for the slow down.
Which wxWidgets version are you using?
I've never read about a similar problem, so i don't think there is a general problem. Can you profile the code and identify any hot spots?
If not, try commenting out parts of the drawing code, maybe you can isolate one particular operation responsible for the slow down.
Use the source, Luke!
-
- Earned a small fee
- Posts: 12
- Joined: Thu Mar 26, 2009 9:03 pm
Re: wxDC Performance OSX (CPU Hog)
Thanks for your reply doublemax.
I've tested it with version 3.0.3 & the 3.1.0, the exact samples as described on the Renderloop page.
Time profiling the render loop with a fixed timer shows me this:
The sample is already very minimal. I tried only calling Refresh(), and disabling the OnPaint event. This still gives me the high cpu load, even when nothing happens!
Hope this helps..
It would be great if another OSX user can confirm this behaviour, as a starting point.
Thanks,
Bart
I've tested it with version 3.0.3 & the 3.1.0, the exact samples as described on the Renderloop page.
Time profiling the render loop with a fixed timer shows me this:
The sample is already very minimal. I tried only calling Refresh(), and disabling the OnPaint event. This still gives me the high cpu load, even when nothing happens!
Hope this helps..
It would be great if another OSX user can confirm this behaviour, as a starting point.
Thanks,
Bart
Last edited by Bartvanstiphout on Sat Dec 23, 2017 6:02 pm, edited 1 time in total.
Re: wxDC Performance OSX (CPU Hog)
Can you give a general outline of what you're doing inside the paint event handler?
Or does it even happen if you don't draw anything?
What's the timer frequency?
Or does it even happen if you don't draw anything?
What's the timer frequency?
Use the source, Luke!
-
- Earned a small fee
- Posts: 12
- Joined: Thu Mar 26, 2009 9:03 pm
Re: wxDC Performance OSX (CPU Hog)
The timer in the sample fires every 10ms, but even when it fires every 20ms, the CPU exceeds 100%, in contrary to the windows version (<10%).
When I comment out the OnPaint event in the EventTable, it still goes to 150% when I maximize the canvas.
The render code isn't that shocking..:
Here is the full code of the timer render sample found at https://wiki.wxwidgets.org/Making_a_render_loop:
Thanks
When I comment out the OnPaint event in the EventTable, it still goes to 150% when I maximize the canvas.
The render code isn't that shocking..:
Code: Select all
void BasicDrawPane::render( wxDC& dc )
{
static int y = 0;
static int y_speed = 2;
y += y_speed;
if(y<0) y_speed = 2;
if(y>200) y_speed = -2;
dc.SetBackground( *wxWHITE_BRUSH );
dc.Clear();
dc.DrawText(wxT("Testing"), 40, y);
}
Code: Select all
#include <wx/sizer.h>
#include <wx/wx.h>
#include <wx/timer.h>
class BasicDrawPane;
class RenderTimer : public wxTimer
{
BasicDrawPane* pane;
public:
RenderTimer(BasicDrawPane* pane);
void Notify();
void start();
};
class BasicDrawPane : public wxPanel
{
public:
BasicDrawPane(wxFrame* parent);
void paintEvent(wxPaintEvent& evt);
void paintNow();
void render( wxDC& dc );
DECLARE_EVENT_TABLE()
};
class MyFrame;
class MyApp: public wxApp
{
bool OnInit();
MyFrame* frame;
public:
};
RenderTimer::RenderTimer(BasicDrawPane* pane) : wxTimer()
{
RenderTimer::pane = pane;
}
void RenderTimer::Notify()
{
pane->Refresh();
}
void RenderTimer::start()
{
wxTimer::Start(10);
}
IMPLEMENT_APP(MyApp)
class MyFrame : public wxFrame
{
RenderTimer* timer;
BasicDrawPane* drawPane;
public:
MyFrame() : wxFrame((wxFrame *)NULL, -1, wxT("Hello wxDC"), wxPoint(50,50), wxSize(400,200))
{
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
drawPane = new BasicDrawPane( this );
sizer->Add(drawPane, 1, wxEXPAND);
SetSizer(sizer);
timer = new RenderTimer(drawPane);
Show();
timer->start();
}
~MyFrame()
{
delete timer;
}
void onClose(wxCloseEvent& evt)
{
timer->Stop();
evt.Skip();
}
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_CLOSE(MyFrame::onClose)
END_EVENT_TABLE()
bool MyApp::OnInit()
{
frame = new MyFrame();
frame->Show();
return true;
}
BEGIN_EVENT_TABLE(BasicDrawPane, wxPanel)
EVT_PAINT(BasicDrawPane::paintEvent)
END_EVENT_TABLE()
BasicDrawPane::BasicDrawPane(wxFrame* parent) :
wxPanel(parent)
{
}
void BasicDrawPane::paintEvent(wxPaintEvent& evt)
{
wxPaintDC dc(this);
render(dc);
}
void BasicDrawPane::paintNow()
{
wxClientDC dc(this);
render(dc);
}
void BasicDrawPane::render( wxDC& dc )
{
static int y = 0;
static int y_speed = 2;
y += y_speed;
if(y<0) y_speed = 2;
if(y>200) y_speed = -2;
dc.SetBackground( *wxWHITE_BRUSH );
dc.Clear();
dc.DrawText(wxT("Testing"), 40, y);
}
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: wxDC Performance OSX (CPU Hog)
I can run a test on 10.9, 10.10 and 10.12 (my 10.11 is currently broken and 10.13 is in my TODO list) if you want.Bartvanstiphout wrote:It would be great if another OSX user can confirm this behaviour, as a starting point.
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
-
- Earned a small fee
- Posts: 12
- Joined: Thu Mar 26, 2009 9:03 pm
Re: wxDC Performance OSX (CPU Hog)
Yes please!
I wonder if it is related to this: https://trac.wxwidgets.org/ticket/17439?
Thanks,
Bart
I wonder if it is related to this: https://trac.wxwidgets.org/ticket/17439?
Thanks,
Bart
Re: wxDC Performance OSX (CPU Hog)
With that simple drawing code, i can only assume that the problem lies somewhere else. What happens if you disable the timer or the paint event handler?
Can you try the sample from here?
viewtopic.php?p=181028#p181028
It was for another purpose, but it contains a small animation and is based on the "minimal" sample that comes with wxWidgets.
Can you try the sample from here?
viewtopic.php?p=181028#p181028
It was for another purpose, but it contains a small animation and is based on the "minimal" sample that comes with wxWidgets.
Use the source, Luke!
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: wxDC Performance OSX (CPU Hog)
Yes, but you have to provide your built test app to run the same copie (knowing it can be due to compiler, IDE, build options, a precise wxWidgets version, underlying SDK...). And if you want I sample from the activity monitor, a debug one will be better, of course.Bartvanstiphout wrote:Yes please!
Last edited by eranon on Sat Dec 23, 2017 8:31 pm, edited 1 time in total.
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
-
- Earned a small fee
- Posts: 12
- Joined: Thu Mar 26, 2009 9:03 pm
Re: wxDC Performance OSX (CPU Hog)
Doublemax, the sample you have provided consumes about 45% CPU, and that is even with a small canvas since this one was not resizable!
Eranon, a binary can be found here:
https://www.dropbox.com/s/bvh0gewg456gd ... t.zip?dl=1
Thanks all,
Bart
Eranon, a binary can be found here:
https://www.dropbox.com/s/bvh0gewg456gd ... t.zip?dl=1
Thanks all,
Bart
Re: wxDC Performance OSX (CPU Hog)
The frame was resizable.Doublemax, the sample you have provided consumes about 45% CPU, and that is even with a small canvas since this one was not resizable!
Anyway, 45% is still too much, maybe the trac ticket you mentioned is indeed describing the same problem.
Use the source, Luke!
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: wxDC Performance OSX (CPU Hog)
OK, here are my tests using your DCtest.app:
Also, not seen any obvious hog function or thread in sampling graph.
Also, not seen any obvious hog function or thread in sampling graph.
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
Re: wxDC Performance OSX (CPU Hog)
I am also experiencing the same problem, and when running the application bartvanstiphout provided my processor load is the following:
-Not resized on hd screen: 14%
-Not resized on retina screen: 19%
-Fit to screen on hd screen: 59%
-Fit to screen on retina screen: 125%
As this DC is indeed very simple, we can't expect this happening. When I run the profiler on the code that was mentioned above, I see 7 or 8 threads that are busy with __vImageCopyBuffer functions, that originate from Apple's Accelerate framework. The main thread is also busy with some Apple function. (see both screenshots below)
^worker thread
^main thread
-Not resized on hd screen: 14%
-Not resized on retina screen: 19%
-Fit to screen on hd screen: 59%
-Fit to screen on retina screen: 125%
As this DC is indeed very simple, we can't expect this happening. When I run the profiler on the code that was mentioned above, I see 7 or 8 threads that are busy with __vImageCopyBuffer functions, that originate from Apple's Accelerate framework. The main thread is also busy with some Apple function. (see both screenshots below)
^worker thread
^main thread