Effective memory management?

Everything else that doesn't fall into one of the other PB categories.
RonStyle
User
User
Posts: 10
Joined: Sat Jan 17, 2004 11:35 pm

Effective memory management?

Post by RonStyle »

Heya,

I'm sure it's just that I'm new to the langauge(not coding), but I'm having a little trouble here, perhaps you can help.

I'm using PB to write an engine, or at least part of an engine, for another language. Obviously, I want to keep all the mesh/surface structs on the pb side, as it offers a lot more control over low-level stuff. I'm just not sure what is the most effective way?

Linked lists seem to be unusable, because I'd need a unique one for each mesh. (For a pool of tris/verts)

AllocateMemory, seems like a good call, but I don't like the idea of re-allocating the entire memory buffer just to add a new vert. Which would mean having to pre-allocate the right size. Fine for non-dynamic meshes.
But imagine something like progressive Vis(I.e a virtual mesh that is dynamically growing/shrinking) and it will cripple the engine.

Using a custom linked list, is also out, because I would then need to create a second list for each tri, so I can index them. It's out because it's an hopefully avoidable bottleneck.

I admit to beng a little shocked that you can't have empty pointers to structs within structures?

Say,

structure Surface
*surface.surf[100],surfCount
endStructure

Doing this, it compiles fine, but whenever I add any code to actually assign a variable I'm stumped. Because PB appears to have no New operator.

I admit it's my experiance in previous languages that is probably the problem here, not anything generally wrong with PB. So any suggestions would be great. I'm going around in cricles, too scared to commit to any idea in case I'm missing something. ;)
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

Ron,

Take a look at this recent discussion:

viewtopic.php?t=9219

Specifically the example given by Freak:

Code: Select all

Structure WORDArray 
  w.w[0] 
EndStructure 

Dim word.w(100) 
word(25) = 1234 


*wptr.WORDArray = @word() 

Debug *wptr\w[25]
Is this what your looking for?
RonStyle
User
User
Posts: 10
Joined: Sat Jan 17, 2004 11:35 pm

Post by RonStyle »

Not really, seems even worse tbh. But thanks for the response, still nice to know.

I need unique lists for each surface structure, and more than one per surface, yet dynamic(I.e shrink and grow, rather than simply reallocating and shifting the old memory(=slow))

In blitz3D for example, i Would achieve it this way, perhaps you know of the pb equlivent(BB is let down in other areas, no pointers etc)


type tri
field blah
end type

type Surface
field tris.tri[100000]
end type


But the field of 100,000 tris is simply empty pointers.

Only once you do this,

test.surface = new surface

test\tri[0] = new tri

is a slot taken,

plus I can then pass it on to other surfaces, *Without* recreating it and using up more memory, since I'm only passing the pointer.

In Pb, there is no apperant way to create an empty pointer. It's automatically filled with the structure, which would cripple my engine's mem usage.

Hope that makes more sense.
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

In purebasic there are no pointer variables, we just signify that a long variable contains an array by adding a * to the front.

So if you want emply pointers, just use longs. When it it time to use it as an array just add the *.

It is still rather clumsy, but it works.

Personally I prefer this approach. Trying to think of an pointer as something in itself always left me cold when working with C. I like to see a pointer for what it is; a long containing a memory address.

Code: Select all

Structure MyPoint
  x.l
  y.l
  z.l
EndStructure

#NumberOfPoints = 100
Structure PointsIndex
  Points.l[#NumberOfPoints]
EndStructure

Global arr.PointsIndex


MessageRequester("Size of array", Str(SizeOf(arr)))

NewList PointsList.MyPoint()

Procedure AddPoint(i, x, y, z)
  If i < #NumberOfPoints 
    ptr = AddElement(PointsList())
    If ptr > 0
      PointsList()\x = x
      PointsList()\y = y
      PointsList()\z = z
      arr\Points[i-1] = ptr + 8 ; Take 1 off i because our index is 1 based.  Add 8 to ptr to allow for the extra values add by linked list
    Else 
      MessageRequester("Error!", "Unable to allocate memory for new element", #PB_MessageRequester_Ok) 
    EndIf
  Else
    MessageRequester("Index out of range", "Unable to allocate memory for new element", #PB_MessageRequester_Ok) 
  EndIf
EndProcedure

Procedure.l GetPoint(i)
  If i < #NumberOfPoints
    ptr = arr\Points[i-1]
    If ptr > 0
      ProcedureReturn ptr
    Else
      MessageRequester("Empty position", "Unable to allocate memory for new element", #PB_MessageRequester_Ok) 
    EndIf
  Else
    MessageRequester("Index out of range", "Unable to allocate memory for new element", #PB_MessageRequester_Ok) 
  EndIf
EndProcedure

Procedure ShowPoint(*p.MyPoint)
  MessageRequester("MyPoint", "(" + Str(*p\x) + ", " + Str(*p\y) + ", " + Str(*p\z) + ")")
EndProcedure
  
AddPoint(5, 10, 11, 12)
AddPoint(20, 20, 21, 22)
AddPoint(99, 30, 31, 32)

ShowPoint(GetPoint(5))
ShowPoint(GetPoint(20))
ShowPoint(GetPoint(99))
Fred
Administrator
Administrator
Posts: 18263
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

just use a pointer:

Code: Select all

  Structure Surface
    *Tris.Tri[10000] ; 10000 empty pointers
  EndStructure
AllocateMemory(0, sizeof(Tri)) to allocate a new element.
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

The one problem with the above is that you can't move the list to the necessary point to delete an entry.

You could get round this by implementing your own linked list.
Saboteur
Enthusiast
Enthusiast
Posts: 273
Joined: Fri Apr 25, 2003 7:09 pm
Location: (Madrid) Spain
Contact:

Post by Saboteur »

In http://www.reelmediaproductions.com/pb, in code snipets section, there is a file called linkedlist.
I think you can insert linked list into structures. Perhaps it helps you.
[:: PB Registered ::]

Win10 Intel core i5-3330 8GB RAM Nvidia GTX 1050Ti
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

GedB wrote:In purebasic there are no pointer variables, we just signify that a long variable contains an array by adding a * to the front.
euhm, this is NOT (entirely) true

Code: Select all

; purebasic survival guide
; pointers.pb - 15.11.2003 ejn (blueznl)
; http://www.xs4all.nl/~bluez/datatalk/pure1.htm
;
; - pointers in purebasic
;
Debug ""
Debug "regular var"
;
a.l = 1             ; create var a
*pointera = a       ; no, this won't work, instead *pointera takes the value of a, not the memaddress
Debug *pointera
*pointera = @a      ; pointer *pointera now points to the memlocation that var a occupies
Debug *pointera
;
c.s = "test"        ; as above, for strings
*pointerc = @c
;
Debug ""
Debug "struct"
;
Structure x         ; things are different with structs
  y1.l
  y2.l
EndStructure
;
b.x                 ; create var b of type struct x
b\y1 = 1
b\y2 = 2
;
Debug b             ; using varname without member gives back the startadres of the struct in memory
Debug @b            ; same thing
Debug @b\y1         ; same thing
;
*pointerb = b       ; create pointer to b
*pointerb = @b      ; same
*pointerb = @b\y1   ; same
;
Debug""
Debug "struct via pointer"
;
*pointerbb.x = b    ; now we get fancy, declare a pointer to a location in memory where a struct is located
;                   ; with the pointer of type structure
;
b\y1 = 3            ; change value
Debug b\y1          ; check
Debug *pointerbb\y1 ; or retrieve it via the pointer, this returns the same value
;
;
; let's say you call a procedure...
; and that procedure returns the address of a struct...
; and you know the structure of the returned data...
; you could read data from that struct using a pointer and struct fields!
;
Debug ""
Debug "dll imitation"
;
; example using the same structure as above
;
b.x
b.x\y1 = 1
b.x\y2 = 2
;
Procedure.l imitation_dll()
  Global b.x
  ;
  b.x\y1 = 3
  ;
  ProcedureReturn @b.x
EndProcedure
;
*pointerbb.x = imitation_dll()
Debug b.x\y1
Debug *pointerbb\y1
;
; this is where the difference between pointers and int's shows up
; the following doesn't work, as you cannot assign vars to structs, which makes sense :-)
; 
; pointerbbb.x = imitation_dll()
;

( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
RonStyle
User
User
Posts: 10
Joined: Sat Jan 17, 2004 11:35 pm

Post by RonStyle »

Lol, nothing like learning a new language to make you feel like a newbie all over again ;)

Thanks guys, I don't entirely understand what you've posted (I'm not even sure you guys do from the sound of it :) (J/k)) but I'll boot up pb and play about with it.

Thx.
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

One simple example:

Code: Select all

a.l = 42
*ptr.LONG = @a
*ptr\l = 34
Debug a
Debug *ptr\l
There are also Structures for BYTE and WORD access

Have fun :!:
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

Ron,

I'm the only one confused, I'm only a few months ahead of yourself.

Thankfully, my understanding is much better now.
Last edited by GedB on Thu Jan 22, 2004 11:43 am, edited 1 time in total.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

RonStyle wrote:Thanks guys, I don't entirely understand what you've posted (I'm not even sure you guys do from the sound of it :)
i certainly don't! :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply