Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.08.12;
Скачать: [xml.tar.bz2];

Вниз

Скорость работы с объектами в Delphi   Найти похожие ветки 

 
Ega23 ©   (2007-07-18 18:04) [40]

Я это всё к чему:
Неужели ты действительно считаешь, что VirtualTreeView работает быстрее ТОЛЬКО из-за того, что там рекорды используются в качестве описателя узла???


 
DevilDevil ©   (2007-07-18 18:40) [41]

> Strange man

Так что тебе надо оптимизировать?
Поподробнее, пожалуйста.


 
Sdubaruhnul   (2007-07-18 19:11) [42]

2 Ega23:

Нет, не только.

Но теперь скажу, к чему я всё это. Привожу текст из справки по VirtualTreeView:

"Aside many other problems one was especially annoying: How can adding some 5000-6000 nodes take a minute or so to finish? This question was the reason that I created the very first version of Virtual Treeview. What I actually did was to recall my studies where I learned my trade. Why, on earth, must everything be wrapped into an object? In Java and the like even simple data types like strings are objects. While this kind of abstraction provides some additional conveniences it costs quite a lot in terms of CPU power and memory, particularly if it comes to many instances of such simple type pretenders.

Basically, the idea of virtualizing the tree control and using records instead of classes were two ideas which are born nearly at the same time. It was quite clear from the very first moment that classes can never be as effective as a simple record structures (in terms of size, access speed and management). Sure, a TPersistent only needs 4 bytes more than a record (the pointer to the class" VMT), but these are still too many extra bytes if you consider that I have wrestled quite a while with myself about every byte in a tree node (and want the minimalism principle). Another point you should not underestimate is that classes as nodes would of course also mean to put node specific methods into this class too, which will be overridden at times (this is the main argument to use a class after all). This will require additional CPU cycles just to lookup access methods, to dereference etc. which in turn will cost extra time. Trees with only some 1000 nodes will never see a large difference but for big trees this is significant and Virtual Treeview has mainly been created to address high capacity tree views."


 
Strange man   (2007-07-18 19:26) [43]


> DevilDevil ©   (18.07.07 18:40) [41]
> > Strange man
>
> Так что тебе надо оптимизировать?
> Поподробнее, пожалуйста.

Я просто пытаюсь понять, насколько замедляет работу программы использование классов. Ты написал, что обращение к записи по указателю и обрашение к классу выполняются с одинаковой скоростью, но у меня в первом случае генерируется 7 команд, а во втором 9... Кстати, обращение к свойствам предков не медленнее? (у меня почему-то тоже 9 команд)


 
DevilDevil ©   (2007-07-19 08:24) [44]

Недопонял, что ты имеешь ввиду. Покажи код+асм. В 2х вариантах: со включённой опцией компилятора и выключенной.

Обращение к свойствам предков не медленнее. Обращение к виртуальным функциям так же одинаково по скорости.


 
Игорь Шевченко ©   (2007-07-19 10:40) [45]


> Another point you should not underestimate is that classes
> as nodes would of course also mean to put node specific
> methods into this class too, which will be overridden at
> times (this is the main argument to use a class after all).
>  This will require additional CPU cycles just to lookup
> access methods, to dereference etc. which in turn will cost
> extra time.


Странно звучит. То есть, для рекордов методы можно выносить отдельно, а для классов обязательно в них самих, да еще и виртуализировать ?
Это Коран такой или Талмуд ?
Любят люди себе проблемы придумывать на ровном месте.


 
DevilDevil ©   (2007-07-19 11:46) [46]

Звучит поерундовски


 
Strange man   (2007-07-19 12:25) [47]


> Недопонял, что ты имеешь ввиду. Покажи код+асм. В 2х вариантах:
>  со включённой опцией компилятора и выключенной.

Какая опция? Оптимизация? Если да, то код получается одинаковый:

with r1 do a := b + c;
 mov eax, [b]
 add eax, [c]
 mov [a], eax

with r2[0] do a := b + c;
 mov eax, [a]
 mov edx, [eax + $04]
 add edx, [eax + $08]
 mov eax, edx

with cl1 do a := b + c;
 mov eax, [xxx]  // Что здесь хранится?
 mov eax, [eax +  $08]
 mov edx, [xxx]
 add eax, [edx + $0c]
 mov edx, [xxx]
 mov [edx + $04], eax


С классом with почему-то не работает :(


> Обращение к свойствам предков не медленнее. Обращение к
> виртуальным функциям так же одинаково по скорости.

Понятно. Просто я слышал, что использование наследования замедляет работу программ


 
oxffff ©   (2007-07-19 12:27) [48]


> > Обращение к свойствам предков не медленнее. Обращение
> к
> > виртуальным функциям так же одинаково по скорости.


По сравнению с чем?


 
Игорь Шевченко ©   (2007-07-19 12:28) [49]


> Обращение к виртуальным функциям так же одинаково по скорости.


Одинаково с чем ?


 
oxffff ©   (2007-07-19 12:38) [50]

To Strange man  

Это для object

mov ebx,[eax+VTB Offset]
..
call [ebx+$MethodOffset]

Это для class

mov ebx,[eax]
..
call [ebx+$MethodOffset]

Если сравнить грубо, то одинаково.


 
Сергей М. ©   (2007-07-19 12:57) [51]


> Strange man   (19.07.07 12:25) [47]


Вместо занятия подобной ловлей блох лучше сосредоточиться на эффективном задействовании расширенных наборов инструкций ЦП - SIMD, MMX, XMM, 3DNow и иже с ними.


 
DevilDevil ©   (2007-07-19 13:17) [52]

> Strange man   (19.07.07 12:25) [47]

Если честно, не совсем понимаю смысл теста, лучше скажи, что в конечном итоге должно быть - мы подскажем слабые места.

> Что здесь хранится?

если там [ebp - что-то], значит сначала он "сохраняет" значение, находящееся в локальной переменной. Локальная переменная - указатель или объект класса.

если вообще какая то константа, то "сохраняет" значение, находящееся в глобальной переменной.

> oxffff ©   (19.07.07 12:27) [48]
> Игорь Шевченко ©   (19.07.07 12:28) [49]

Обращение к виртуальным методам предков по сравнению с обращением к методам потомков.

> Понятно. Просто я слышал, что использование наследования
> замедляет работу программ


На практике часто это правда. Зависит только от программста. Уменьшение в скорости если вызываешь, скажем, inherited.


 
DevilDevil ©   (2007-07-19 13:18) [53]

> Сергей М. ©   (19.07.07 12:57) [51]
> > Strange man   (19.07.07 12:25) [47]Вместо занятия подобной
> ловлей блох лучше сосредоточиться на эффективном задействовании
> расширенных наборов инструкций ЦП - SIMD, MMX, XMM, 3DNow
> и иже с ними.


А вот этого точно использовать не надо:
1) имхо
2) вряд ли это может пригодиться в твоей задачи
3) врядли осилишь реализацию


 
DevilDevil ©   (2007-07-19 13:21) [54]

SIMD - это и есть общее определение для всех расширенных наборов инструкций ЦП. XMM - это названия регистров. А вообще MMX, SSE(1, 2, 3), 3Dnow - этоже вроде SSE.

SIMD - имхо муть!


 
oxffff ©   (2007-07-19 13:25) [55]


> Обращение к виртуальным методам предков по сравнению с обращением
> к методам потомков


Вызов обычного метода или виртуального через inherited линкуется напрямую.

Вызов виртуального метода  происходит через VTB, т.е + 2 fetch из памяти.
Один VTB, второй entry point.

Так что разница между этими вызовами есть.


 
oxffff ©   (2007-07-19 13:30) [56]


> SIMD - это и есть общее определение для всех расширенных
> наборов инструкций ЦП.


AMD64 тоже расширение набора. Но не SIMD.

The AMD64 architecture is a simple yet powerful 64-bit, backward-compatible extension of the industry-standard (legacy) x86 architecture.


 
Сергей М. ©   (2007-07-19 13:40) [57]


> вряд ли это может пригодиться в твоей задачи


Это не моя задача)


> врядли осилишь реализацию


Да что ты ?!)


> SIMD - имхо муть


Угу. Просто так придуман, не для вас, игролепов-блохоловов)


 
Strange man   (2007-07-19 13:43) [58]


> Если честно, не совсем понимаю смысл теста, лучше скажи,
>  что в конечном итоге должно быть - мы подскажем слабые
> места.

Объясни пожалуйста, как заставить компилятор генерировать

mov eax, [xxx + $04]
mov edx, [eax + $04]
add edx, [eax + $08]
mov eax, edx


или хотя бы

mov eax, [xxx]
mov edx, [eax + $08]
add edx, [eax + $0c]
mov [eax + $04], edx


вместо

mov eax, [xxx]  
mov eax, [eax +  $08]
mov edx, [xxx]
add eax, [edx + $0c]
mov edx, [xxx]
mov [edx + $04], eax


А то полулучается медленнее в полтора раза


> если там [ebp - что-то], значит сначала он "сохраняет" значение,
>  находящееся в локальной переменной. Локальная переменная
> - указатель или объект класса.
>
> если вообще какая то константа, то "сохраняет" значение,
>  находящееся в глобальной переменной.

Нет, там просто смещение.

У меня класс
TC = class
  a, b, c: Integer;
  procedure Proc;
end;


А xxx - это [a - 4]. Что это может быть?


 
DevilDevil ©   (2007-07-19 14:03) [59]

> Сергей М. ©   (19.07.07 13:40) [57]

Я цитировал тебя, а обращался к нему.

> Strange man   (19.07.07 13:43) [58]

mov eax, [xxx]  // занести в eax значение переменной
mov eax, [eax +  $08] // buf := eax.SomeField;
mov edx, [xxx] // занести в edx значение переменной2
add eax, [edx + $0c] // buf := buf + edx.SomeField2;
mov edx, [xxx] // занести в edx значение переменной3
mov [edx + $04], eax // edx.SomeField3 := buf;


врядли можно заставить компилятор это с оптимизировать. Хотя, всё может быть, поставь оптимизацию в опциях компилятора, может Delphi "сотворит чудо"

1) говори, какая у тебя итоговая задача
2) показывай код, который был переведён компилятором в такой асм-код


 
Strange man   (2007-07-19 14:45) [60]


> DevilDevil ©   (19.07.07 14:03) [59]

Вот код с записью (r2: array of TR; setLength(r2, 1)):

with r2[0] do a := b + c;

mov eax, [a]               // Все расчёты ведём относительно первого поля "a"
mov edx, [eax + $04]   // edx = b
add edx, [eax + $08]    // edx = b + c
mov eax, edx              // eax = a = b + c


Здесь всё как надо. Смещение записи запоминается один раз. Тогда по логике и с классом должно быть также(cl: TC):

with cl do a := b + c;

mov eax, [xxx]             // Все расчёты ведём относительно смещения [xxx]
mov edx, [eax + $08]    // edx = b
add edx, [eax + $0c]    // edx = b + c
mov [eax + $04], edx   // a = edx = b + c


НО на практике получается так

with cl do a := b + c;

mov eax, [xxx]                    // 1
mov eax, [eax +  $08]          // eax = b
mov edx, [xxx]                    // 2
add eax, [edx + $0c]           // eax = b + c
mov edx, [xxx]                   // 3
mov [edx + $04], eax          // a = eax = b + c


Почему смещение [xxx] запоминается 3 раза? Это особенность использования классов? Это первый вопрос.

А второй вопрос: почему расчёты ведутся относительно [xxx], а не относительно первого поля "a"? Что находится в [xxx]?


 
Сергей М. ©   (2007-07-19 15:09) [61]


> with cl do a := b + c;


Мало ли в Бразилии "Педро" ?)

Строчка

with MyClass.Create(..) do a := b + c;

дает блохоловам ровно три asm-инструкции)


 
oxffff ©   (2007-07-19 15:10) [62]


> Что находится в [xxx]?


[xxx] Адрес объекта.
[ [xxx] ] адрес VTB
[[xxx]+$04] значение первого поля a


 
DevilDevil ©   (2007-07-19 15:18) [63]

ээээмм..

1) самое быстрое обращение будет к полям r1
2) r2 - переменная, хранящая указатель на r2[0]; переменная-динамический массив содержит указатель на первый элемент такого массива.
3) сделай r3 : ^TR. Проинициализируй и попробуй к нему так же обращаться. Скорее всего выйдет так же, как с классом.
4) попробуй выставить в опциях компилятора оптимизацию и сделай Build проекту. Мне кажется, инициализация одной и той же константой пройдёт.
5) указатель на рекорд = равен указателю на первый его элемент. так же как и с массивами. С классами иначе. Кроме заданных тобой данных, класс содержит некоторые свои данные (указатель на таблицу методов, например), надо посмотреть TObject.


 
Strange man   (2007-07-19 16:10) [64]


> Сергей М. ©   (19.07.07 15:09) [61]
> > with cl do a := b + c;
> Мало ли в Бразилии "Педро" ?)
> Строчка
> with MyClass.Create(..) do a := b + c;
> дает блохоловам ровно три asm-инструкции)

Но мне не надо вызывать create, класс уже создан, мне надо только изменить поле а.

> oxffff ©   (19.07.07 15:10) [62]
> [ [xxx] ] адрес VTB
>
> DevilDevil ©   (19.07.07 15:18) [63]
> Кроме заданных тобой данных, класс содержит некоторые свои
> данные

vtb - это виртуальная таблица чего-то? :) Где можно прочитать об этом?

> надо посмотреть TObject

В справке про vtb ничго не сказано

> сделай r3 : ^TR. Проинициализируй и попробуй к нему так
> же обращаться. Скорее всего выйдет так же, как с классом.

Если
var pr: ^tr;
pr:=@r1;
with pr^ do a:=b+c;

то код генерируется такой же, как для r2[0]. Или я не то сделал?

> выставить в опциях компилятора оптимизацию

Оптимизация у меня включена была с самого начала


 
DevilDevil ©   (2007-07-19 16:17) [65]

VMT - таблица виртуальных методов.

Пример. У каждого класса есть виртуальный метод Destroy. Если в своём классе ты напишешь виртуальный метод Destroy, то в таблице на месте метода Destroy будет содержаться указатель на твой метод Destroy, а не на метод твоего предка.

> то код генерируется такой же, как для r2[0]. Или я не то
> сделал?> выставить в опциях компилятора оптимизацию Оптимизация
> у меня включена была с самого начала


что то здесь не чисто...


 
DevilDevil ©   (2007-07-19 16:49) [66]

Я провёл тест. Гы!

Если написать pr.a := pr.b + pr.c;
тогда будет как с классом. :)

То есть with для классов не делает оптимизации, а для record-ов делает.

Потестите кто-нибудь на TurboDelphi, может лучше стало.


 
Strange man   (2007-07-19 17:01) [67]


> DevilDevil ©   (19.07.07 16:49) [66]
>
> Если написать pr.a := pr.b + pr.c;
> тогда будет как с классом. :)
>
> То есть with для классов не делает оптимизации, а для record-
> ов делает.

Так и есть :) Выходит у записей всё-таки преимущество перед классами :)
Большое спасибо!


 
DevilDevil ©   (2007-07-19 17:15) [68]

в "защиту" классов всё же скажу:

1) надеюсь, в TurboDelphi всё будет исправлено. А даже если не в Turbo, то в следующих версиях.

2) если с объектом предполагается проделать множество действий, то имеет смысл написать функцию, одним из параметров в которой будет этот класс. Или это будет метод этого же класса. В таком случае указатель на данные класса сразу будет храниться в регистре.

P.S.
> Большое спасибо!


Нет, нет, так просто ты не отделаешься!
Рассказывай, что у тебя за задача такая? Не расскажешь подробно - повешусь, тебя потом всю жизнь совесть будет мучать!


 
Strange man   (2007-07-19 17:48) [69]


> Нет, нет, так просто ты не отделаешься!
> Рассказывай, что у тебя за задача такая? Не расскажешь подробно
> - повешусь, тебя потом всю жизнь совесть будет мучать!

Да всё гораздо проще. Просто хочу написать игру, вот сначала и выясняю, стоит использовать классы, или нет, чтобы не делать грубых ошибок :) На первый взгляд вроде мелочь, а как оказалось, разница в скорость в полтора раза...


 
DevilDevil ©   (2007-07-19 18:07) [70]

Это не то место, которое надо оптимизировать!

Оптимизировать надо вывод графики.

- для 3D не выводить неотображаемые участки, оптимизация геометрии.
- стараться не использовать больших текстур (1024x1024) имхо уже много
- по возможности сжимать текстуры
- отработать механизм: хранить, какая в последний раз была активизирована текстура. и, если нужны, её размеры . Не активировать текстуру, которая была активирована последней.
- минимизировать "переключение" текущей текстуры.

Такая оптимизация даст прирост в разы.
Оптимизируя доступ к полям, ты не получишь и процента!

А что ты там хочешь record-ами делать.
Если удобнее классами, делай классами!

P.S. первый закон оптимизации: "оптимизировтаь надо слабые места!"


 
Strange man   (2007-07-19 18:12) [71]


> - по возможности сжимать текстуры
> - отработать механизм: хранить, какая в последний раз была
> активизирована текстура. и, если нужны, её размеры . Не
> активировать текстуру, которая была активирована последней.
>
> - минимизировать "переключение" текущей текстуры.
>
> Такая оптимизация даст прирост в разы.

Спасибо, учту


 
DevilDevil ©   (2007-07-19 18:38) [72]

не буду отвечать на вопросы в следующий раз, ну на фиг!

Я ему тут печатаю-печатаю, а он про рекорды рассказать не может...


 
oxffff ©   (2007-07-19 18:58) [73]


> Спасибо, учту


LOL.

Ты бы лучше дружок занялся нормальной оптимизацией BSP, portals, octree.

А лучше бы открыл бы SDK DIRECT 3D. И почитал.

General Performance Tips
Follow these general guidelines to increase the performance of your application.

Clear only when you must.
Minimize state changes and group the remaining state changes.
Use smaller textures, if you can do so.
Draw objects in your scene from front to back.
Use triangle strips instead of lists and fans. For optimal vertex cache performance, arrange strips to reuse triangle vertices sooner, rather than later.
Gracefully degrade special effects that require a disproportionate share of system resources.
Constantly test your application"s performance.
Minimize vertex buffer switches.
Use static vertex buffers where possible.
Use one large static vertex buffer per flexible vertex format (FVF) for static objects, rather than one per object.
If your application needs random access into the vertex buffer in accelerated graphics port (AGP) memory, choose a vertex format size that is a multiple of 32 bytes. Otherwise, select the smallest appropriate format.
Draw using indexed primitives. This can allow for more efficient vertex caching within hardware.
If the depth buffer format contains a stencil channel, always clear the depth and stencil channels at the same time.
Combine the shader instruction and the data output where possible. For example:

P.S.

Для классов.
У меня в любом случае 3 инструкции, что с with, что без
Что я не так делаю?


 
DevilDevil ©   (2007-07-19 19:07) [74]


> oxffff ©   (19.07.07 18:58) [73]

какая версия, больше 6 ?


 
oxffff ©   (2007-07-19 19:08) [75]

7


 
Strange man   (2007-07-19 22:05) [76]


> DevilDevil ©   (19.07.07 18:38) [72]

Извини)
Ну во первых рекорды в любом случаенезаменимы при написании геометрических объектов (векторов, матриц, сфер и т. д.). Ну а вопрос то был в том, что использовать для описания такких объектов, как боты, оружее, карты и т. д. Сейчас думаю использовать рекорды.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.08.12;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.63 MB
Время: 0.051 c
15-1184522210
Yanis
2007-07-15 21:56
2007.08.12
Новое веяние спама: pdf файлы. Обнаружил в почте.


2-1184308818
Kolan
2007-07-13 10:40
2007.08.12
Почему один пакет не видит, что в другом пакете есть класс?


2-1184580673
httpbeginer
2007-07-16 14:11
2007.08.12
создание строки HTTP запроса


1-1180427774
alexander_nt
2007-05-29 12:36
2007.08.12
Скопировать содержимое TWebBrowser


2-1184491327
>>DEATH<<
2007-07-15 13:22
2007.08.12
сслки из хтмл кода





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский