Я мог бы понять столь значительную загрузку центрального процессора, если бы использовалась крутейшая 3D графика, от которой к примеру видеокарта захлебывалась бы при обсчете вершин полигонов в процессе создания геометрии объектов (хотя по моему глубокому убеждению даже эта задача является задачей видеокарты). Но в данном случае речь идёт об операциях с графическими примитивами. Если взять SharpGears, то и в нём используются несложные графические операции, не говоря уже о совсем примитивных операциях в тестах с точками. В них сглаживания даже близко нет (например тест c ZedGraph). И такой чудесный результат - 100% загрузка центрального процессора. Чем же он интересно занят? Просчетом в какое место вонзить следующую точку?
Ради интереса достал старый добрый Delphi 6.0 и слепил аналогию теста с ZedGraph, только теперь уже с использованием TChart'а:
код -
исходники -
Результат аналогичный - 100% загрузка процессора. Ужас. Какой из тестов данной темы не запустишь - загрузка CPU 100%. Придется искать ПК с Win'98, где использовалась GDI без плюсов, и там проверить работу теста с TChart.
Закончим с лирикой и вернемся к теме.
В процессе обсуждения темы были получены противоречивые результаты:
v567 писал(а): ↑01.05.2009 03:11
kamre писал(а): ↑30.04.2009 22:37
Так оно вообще "аццки" тормозит и больше 11 FPS не показывает. Запускал в "Mono-2.4 Command Prompt" через "mono SharpGears.exe".
Получается, что mono на Вашем пк показал результаты: в xp 11 fps, а в opensuse 36 fps. Т.е. mono в opensuse отработал в 3 раза шустрее, чем в xp. Мой же тест (с zedgraph) показал другие результаты для mono: в xp 7.7 сек, в opensuse 494.2 сек. Т.е. mono в opensuse отработал в 64 раза медленнее, чем в xp!!!
Ещё раз посмотрел в профайле работу тестов (test.exe с ZedGraph и SharpGears) в MS-Windows и Linux.
MS-Windows (
mono --profile test.exe > test_win.txt):
Linux (
mono --profile test.exe > test_lin.txt):
MS-Windows (
mono --profile sharpgears.exe > sharp_win.txt):
Linux (
mono --profile SharpGears.exe > sharp_lin.txt):
test_win.txt:
Код: Выделить всё
Time(ms) Count P/call(ms) Method name
########################
9914.255 1799 5.511 System.Windows.Forms.Control::Refresh()
1260 70 % System.Windows.Forms.Control::Refresh()
500 27 % Test.TestForm::Tm()
########################
9884.213 506 19.534 System.Windows.Forms.XplatUI::UpdateWindow(intptr)
502 99 % System.Windows.Forms.Control::Refresh()
########################
9874.198 506 19.514 System.Windows.Forms.XplatUIWin32::UpdateWindow(intptr)
506 100 % System.Windows.Forms.XplatUI::UpdateWindow(intptr)
########################
9874.198 506 19.514 System.Windows.Forms.XplatUIWin32::Win32UpdateWindow(intptr)
506 100 % System.Windows.Forms.XplatUIWin32::UpdateWindow(intptr)
########################
19948.684 1173 17.007 System.Windows.Forms.XplatUIWin32::InternalWndProc(intptr,Msg,intptr,intptr)
501 42 % System.Windows.Forms.XplatUIWin32::Win32UpdateWindow(intptr)
241 20 % System.Windows.Forms.XplatUIWin32::Win32GetMessage(MSG&,intptr,int,int)
134 11 % System.Windows.Forms.XplatUIWin32::Win32DispatchMessage(MSG&)
########################
19948.684 1173 17.007 System.Windows.Forms.NativeWindow::WndProc(intptr,Msg,intptr,intptr)
1173 100 % System.Windows.Forms.XplatUIWin32::InternalWndProc(intptr,Msg,intptr,intptr)
########################
19948.684 1167 17.094 .ControlNativeWindow::WndProc(Message&)
1167 100 % System.Windows.Forms.NativeWindow::WndProc(intptr,Msg,intptr,intptr)
########################
19948.684 1167 17.094 .ControlWindowTarget::OnMessage(Message&)
1167 100 % .ControlNativeWindow::WndProc(Message&)
Получим:
1). Tm() -> Control::Refresh -> XplatUI::UpdateWindow -> XplatUIWin32::UpdateWindow -> XplatUIWin32::Win32UpdateWindow
2). XplatUIWin32::Win32UpdateWindow -> XplatUIWin32::InternalWndProc -> NativeWindow::WndProc -> ControlWindowTarget::OnMessage
test_lin.txt:
Код: Выделить всё
Time(ms) Count P/call(ms) Method name
########################
502527,899 1801 279,027 System.Windows.Forms.Control::Refresh()
Callers (with count) that contribute at least for 1%:
1260 69 % System.Windows.Forms.Control::Refresh()
500 27 % Test.TestForm::Tm()
########################
502504,858 508 989,183 System.Windows.Forms.XplatUI::UpdateWindow(intptr)
504 99 % System.Windows.Forms.Control::Refresh()
########################
502502,880 508 989,179 System.Windows.Forms.XplatUIX11::UpdateWindow(intptr)
508 100 % System.Windows.Forms.XplatUI::UpdateWindow(intptr)
########################
503021,459 563 893,466 System.Windows.Forms.XplatUIX11::SendMessage(intptr,Msg,intptr,intptr)
507 90 % System.Windows.Forms.XplatUIX11::UpdateWindow(intptr)
13 2 % System.Windows.Forms.XplatUIX11::CreateWindow(CreateParams)
9 1 % System.Windows.Forms.XplatUIX11::GetMessage(object,MSG&,intptr,int,int)
########################
1009427,130 1282 787,385 System.Windows.Forms.NativeWindow::WndProc(intptr,Msg,intptr,intptr)
563 43 % System.Windows.Forms.XplatUIX11::SendMessage(intptr,Msg,intptr,intptr)
546 42 % System.Windows.Forms.XplatUIX11::DispatchMessage(MSG&)
83 6 % System.Windows.Forms.XplatUIX11::GetMessage(object,MSG&,intptr,int,int)
########################
1009384,710 875 1153,583 .ControlNativeWindow::WndProc(Message&)
875 100 % System.Windows.Forms.NativeWindow::WndProc(intptr,Msg,intptr,intptr)
########################
1009376,983 875 1153,574 .ControlWindowTarget::OnMessage(Message&)
875 100 % .ControlNativeWindow::WndProc(Message&)
Получим:
1). Tm() -> Control::Refresh -> XplatUI::UpdateWindow -> XplatUIX11::UpdateWindow
2). XplatUIX11::UpdateWindow -> XplatUIX11::SendMessage -> NativeWindow::WndProc -> ControlNativeWindow::WndProc -> ControlWindowTarget::OnMessage
Различия:
XplatUIWin32::Win32UpdateWindow -> XplatUIWin32::InternalWndProc -> NativeWindow::WndProc
XplatUIX11::UpdateWindow -> XplatUIX11::SendMessage -> NativeWindow::WndProc
Прямой вызов процедуры InternalWndProc эффективнее, чем отправка SendMessage'а оконной системе X Window. Метод SendMessage отправляет сообщение окну и управление не возвращается до обработки данного сообщения. Вероятно этим и объясняется повышенная тормознутость в работе теста с ZedGraph в Linux.
С тестом SharpGears дело обстоит несколько иначе. Метод SendMessage в Linux практически не используется. Обработка идёт не прямой перерисовкой (Refresh), а заменой обработчика onPaint. Поэтому цепочки вызывов схожи как в Linux, так и в MS-Windows. Явных отличий нет.
Можно предположить, что тормознутость SharpGears в MS-Windows (под mono) связана с кривой реализацией операций с векторными примитивами. Так в отрывках ниже метод
GdipFillPath выполняется в Linux в 2.3 раза быстрее (3.365 / 1.455), чем в MS-Windows (под mono). Поскольку SharpGears в MS-Windows под .NET отрабатывает намного быстрее, чем в Linux, то иначе как кривым использованием библиотеки GDI+ со стороны mono объяснить нельзя.
sharp_win.txt:
Код: Выделить всё
Time(ms) Count P/call(ms) Method name
########################
26347.906 7830 3.365 System.Drawing.GDIPlus::GdipFillPath(intptr,intptr,intptr)
7830 100 % System.Drawing.Graphics::FillPath(Brush,GraphicsPath)
########################
19167.529 3915 4.896 System.Drawing.GDIPlus::GdipDrawPath(intptr,intptr,intptr)
3915 100 % System.Drawing.Graphics::DrawPath(Pen,GraphicsPath)
########################
6559.433 26535 0.247 System.Drawing.GDIPlus::GdipFillEllipse(intptr,intptr,single,single,single,single)
26535 100 % System.Drawing.Graphics::FillEllipse(Brush,single,single,single,single)
########################
2363.397 5220 0.453 System.Drawing.GDIPlus::GdipDrawEllipse(intptr,intptr,single,single,single,single)
5220 100 % System.Drawing.Graphics::DrawEllipse(Pen,single,single,single,single)
########################
4336.249 871 4.978 System.Drawing.GDIPlus::GdipFillRectangleI(intptr,intptr,int,int,int,int)
871 100 % System.Drawing.Graphics::FillRectangle(Brush,int,int,int,int)
sharp_lin.txt:
Код: Выделить всё
Time(ms) Count P/call(ms) Method name
########################
21370,793 14688 1,455 System.Drawing.GDIPlus::GdipFillPath(intptr,intptr,intptr)
14688 100 % System.Drawing.Graphics::FillPath(Brush,GraphicsPath)
########################
10092,740 7344 1,374 System.Drawing.GDIPlus::GdipDrawPath(intptr,intptr,intptr)
7344 100 % System.Drawing.Graphics::DrawPath(Pen,GraphicsPath)
########################
5762,369 49776 0,116 System.Drawing.GDIPlus::GdipFillEllipse(intptr,intptr,single,single,single,single)
49776 100 % System.Drawing.Graphics::FillEllipse(Brush,single,single,single,single)
########################
4049,272 9792 0,414 System.Drawing.GDIPlus::GdipDrawEllipse(intptr,intptr,single,single,single,single)
9792 100 % System.Drawing.Graphics::DrawEllipse(Pen,single,single,single,single)
########################
48,426 1632 0,030 System.Drawing.GDIPlus::GdipFillRectangleI(intptr,intptr,int,int,int,int)
1632 100 % System.Drawing.Graphics::FillRectangle(Brush,int,int,int,int)
Кто что думает по этому поводу?

У вас нет необходимых прав для просмотра вложений в этом сообщении.