Recent

Author Topic: TObject memory use  (Read 16099 times)

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4715
  • I like bugs.
Re: TObject memory use
« Reply #15 on: October 17, 2011, 12:01:37 am »
Its actually bit difficult to test or observe memory use for class objects. I do hope you are right that their definition counts just once. Only what i observed was that adding 2 simple setter procedures to the TParticle class, added program memory by tens of thousands of bytes.

I don't know what could cause that.


Quote
I know that 10000 particles would still work smoothly with class objects but for game programming every bit is important. It could mean a little framerate loss or time that could be used in calculating physics or something else. Even if you aim to make an engine that wouldn't require a top notch year 2011 computer, but work on a little older computers too.

When i delete a particle it does just this, moves last index in place of removed index, and that only works if i go the array through from "pCount-1 downto 0":
Code: [Select]
      if a<=0 then begin // a is particle transparency channel
        dec(pCount); pt[i]:=pt[pCount];
      end;

Does it move more than 1 element? Moving memory is always an expensive operation.

Quote
For texture array and some other classes i have earlier made this kind of procedure:
Code: [Select]
procedure TTextureSet.SetCount(n: integer);
begin
  count:=n; n:=nxMath.pow2fit(n);
  if n<>count2 then begin
    count2:=n; setlength(texture,count2);
  end;
end;
Basically it only calls setlength() for power of 2, only when the size must be increased. So if item count increases to 257 it will increase array to 512, and not increase that until item count reach 513, and then adds to 1024. I could use this for particles later possibly, but there is that little slowdown calling pow2fit(), but it would still be propably faster than calling setlength every time.

I think I guess what nxMath.pow2fit(n) does but based on the explanation you should multiply the array's capacity by 2 when more room is needed.
It can be optimized into a SHR operator (the compiler may optimize it?).
Name "SetCount" here is misleading. Change it to "SetCapacity". For an example see:
function TFPList.Expand: TFPList;
in RTL sources.

Quote
By the way, is that even beneficial for the dynamic memory manager or should i just increase it in like steps of 500 each time? It would at least count it way faster without need for logarithm functions. I mean, it just struck me 1 day that powers of 2 might feel "computer friendly numbers"  :D

I don't think it makes any real difference.

Juha
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12888
  • FPC developer.
Re: TObject memory use
« Reply #16 on: October 17, 2011, 02:06:17 pm »
Its actually bit difficult to test or observe memory use for class objects. I do hope you are right that their definition counts just once. Only what i observed was that adding 2 simple setter procedures to the TParticle class, added program memory by tens of thousands of bytes.

program memory? What does program memory (read: .exe size) have to do with it?

In two or three messages, speed, data memory and program memory have surfaced. Now, what exactly is the metric that is the important one? And no, smaller .exe is not necessarily faster.

Quote
I know that 10000 particles would still work smoothly with class objects but for game programming every bit is important. It could mean a little framerate loss or time that could be used in calculating physics or something else. Even if you aim to make an engine that wouldn't require a top notch year 2011 computer, but work on a little older computers too.

Such bits are not as black and white as you might think. There are many, many tunable variables.

Quote
When i delete a particle it does just this, moves last index in place of removed index, and that only works if i go the array through from "pCount-1 downto 0":
Code: [Select]
      if a<=0 then begin // a is particle transparency channel
        dec(pCount); pt[i]:=pt[pCount];
      end;

For instance, the performance of this example depends on if the [] operator is  a simple array access, or some property that calls a procedure (like in tlist).

So take a step back, and start describing the most speed dependent parts as abstract as possible.

Quote

By the way, is that even beneficial for the dynamic memory manager or should i just increase it in like steps of 500 each time? It would at least count it way faster without need for logarithm functions. I mean, it just struck me 1 day that powers of 2 might feel "computer friendly numbers"  :D

Small blocks are handled by the memory manager, it allocates a large block (think 1,2MB) from the OS, and then suballocates itself. Larger allocations are done directly from the OS.

FAllocation from the OS goes in pages.  Pages are typically 4096 byte on 32-bit and iirc 8192 on 64-bit, but in there are options to make them larger (64kb or a 1 MB) in situations with a lots, lots of memory.
BUT, these blocks might contain a bit of overhead for the heapmanager, so allocating a multiple of the page size is not entirely ideal.

Anyway, in general the doubling is a good strategy, but only to a certain maximum.  After that maximum is reached increasing with a large but fixed number is better.

If you only have one or a handful of these list (e.g. the list with particles) then take the maximum big (say 256kb or 1MB), and the increment after also large. If the list is not entirely full, it will only be hundreds of kbs or a few MB at best that are lost. Even 7 year old machines typically have hundreds of MBs of memory.

If you use a list e.g. inside the tparticle class, and every particle might have one, things are different. Both values are then small, since the slack (even if only a few thousand bytes) goes times the number of particles.
 

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: TObject memory use
« Reply #17 on: October 17, 2011, 08:40:51 pm »
program memory? What does program memory (read: .exe size) have to do with it?
Not .exe size, i observe task manager processes that's memory (RAM). That is different to the size on the disk.

And i have already sorted any possible speed issues, my particle counts are in 100000's, with over 120 Frames per second. I set the setlength() allocate in steps of 1000 at the time. But if particle is removed the count must go under by 2000 before it reduces capacity by 1000. That fixes even case where particle count would vary between 900-1100 and repeatedly change capacity.

Quote
Quote
When i delete a particle it does just this, moves last index in place of removed index, and that only works if i go the array through from "pCount-1 downto 0":
Does it move more than 1 element? Moving memory is always an expensive operation.
No, only 1.
« Last Edit: October 17, 2011, 10:14:11 pm by User137 »

 

TinyPortal © 2005-2018