zerkle@iris.ucdavis.edu (Dan Zerkle) (01/10/91)
I recently wrote a vector graphics package that had to allocate and de-allocate huge amounts of small structures with malloc. I noticed that it seemed to be running awfully slowly for some reason. When I wrote my own memory manager instead, the program ran three times faster. People running similar stuff on Unix (for the same class) noticed that their programs didn't spend a lot of time on memory management (according to the profiler). So: Why does the Amiga spend so much time fooling around with memory management? Is the behavior I noted typical? Also, this same program's memory manager would allocate a large chunk of memory at the beginning of the program (and in the middle, actually), but I never bothered to de-allocate the memory before exiting. I never noticed any problems with this, and the status line showed as much memory before execution as after. That doesn't mean that there wasn't a potential for problems. Does anybody know about this? Was I doing a bad thing? Should I explicitly de-allocate the memory before exiting, or just count on "the system" to take care of it? If it matters: A3000 under 2.02, Aztec C 5.0d. Dan Zerkle zerkle@iris.eecs.ucdavis.edu (916) 754-0240 Amiga... Because life is too short for boring computers.
mwm@raven.relay.pa.dec.com (Mike (My Watch Has Windows) Meyer) (01/10/91)
In article <8135@ucdavis.ucdavis.edu> zerkle@iris.ucdavis.edu (Dan Zerkle) writes:
I recently wrote a vector graphics package that had to allocate and
de-allocate huge amounts of small structures with malloc. I noticed
that it seemed to be running awfully slowly for some reason. When I
wrote my own memory manager instead, the program ran three times
faster. People running similar stuff on Unix (for the same class)
noticed that their programs didn't spend a lot of time on memory
management (according to the profiler).
So: Why does the Amiga spend so much time fooling around with memory
management? Is the behavior I noted typical?
The key is noticing that you're using Manx, not Lattice. Manx
malloc/free goes to the system (AllocMem/FreeMem), which have to deal
with linked lists of all the memory in the system. The Unix
malloc/free (and presumably, your code) allocate large chunks of
memory, and most malloc/free calls don't go to the exec. The libraries
have a simpler problem than the Amiga exec, and so tend to run
noticably faster.
Also, this same program's memory manager would allocate a large chunk
of memory at the beginning of the program (and in the middle,
actually), but I never bothered to de-allocate the memory before
exiting. I never noticed any problems with this, and the status line
showed as much memory before execution as after. That doesn't mean
that there wasn't a potential for problems. Does anybody know about
this? Was I doing a bad thing? Should I explicitly de-allocate the
memory before exiting, or just count on "the system" to take care of
it?
The system isn't taking care of it; the library is. The exit code from
the compiler will make sure any hanging malloc's get dealt with. This
is SOP, and you shouldn't worry about it. Some will argue that it's
better style to deallocate the memory yourself, but either way is
safe.
If it matters: A3000 under 2.02, Aztec C 5.0d.
Yes, it matter. Lattice does things the way Unix does - by allocating
large chunks, and using those. While testing this, I saw as much as an
order of magnitude more speed from Lattices's malloc/free than from
AllocMem/FreeMem. Manx malloc/free adds a layer around the
AllocMem/FreeMem, and so can be expected to run slower than
AllocMem/FreeMem. The advantage of Manx's way of doing things is that
free()'ed memory is given back to the system, whereas Lattice will
hang on to it until the program terminates. This causes problems in
some situations.
<mike
--
giguere@csg.uwaterloo.ca (Eric Giguere) (01/10/91)
Routines like "malloc" and "free" are not Amiga-specific routines. These routines are provided by the C library you're linking to. They eventually call the Amiga routines AllocMem and FreeMem to get and free the memory, but also keep track of the memory your program is using (something which AllocMem/FreeMem won't do) and make sure all the memory is returned to the system when your program exits. If you're concerned about efficiency, you should use the low-level AllocMem call. However, you'll have to make sure that your program returns every single piece of memory it allocates! (AllocMem is also useful if you need to explicitly get CHIP memory.) If you're allocating and deallocating a lot of small items repeatedly, it might be worth it to allocate one large chunk of memory at the beginning of your program and do the assignments within that chunk yourself. Also, Intuition has an AllocRemember function to help with that kind of activity. -- Eric Giguere giguere@csg.UWaterloo.CA Quoth the raven: "Eat my shorts!" --- Poe & Groening
cunniff@hpfcso.HP.COM (Ross Cunniff) (01/11/91)
In article <MWM.91Jan9150459@raven.relay.pa.dec.com> mwm@raven.relay.pa.dec.com (Mike (My Watch Has Windows) Meyer) says: > Yes, it matter. Lattice does things the way Unix does - by allocating > large chunks, and using those. While testing this, I saw as much as an > order of magnitude more speed from Lattices's malloc/free than from > AllocMem/FreeMem. Manx malloc/free adds a layer around the > AllocMem/FreeMem, and so can be expected to run slower than > AllocMem/FreeMem. The advantage of Manx's way of doing things is that > free()'ed memory is given back to the system, whereas Lattice will > hang on to it until the program terminates. This causes problems in > some situations. It was for this reason that I wrote my own version of malloc(), free(), and realloc() that got fairly large (multiples of 2K? I forget) buffers via AllocMem(), handed pieces out to satisfy malloc() requests, and when all of the pieces in the chunk were free()d returned the memory to the OS via FreeMem(). This was FASTER than the standard Lattice malloc(), free(), and realloc(); however, it doesn't satisfy the Un*x requirement that free()d blocks be accessible until the next malloc(); i.e. UN*X allows the following: for( ptr = head; ptr; ptr = ptr->next ) free( ptr ); which looks at ptr->next AFTER ptr has been free()d; a real no-no if you have returned the memory to the OS. Of course, being the nice guy that I am, I don't do this :-) If Manx indeed does things the way you describe, a fair amount of ported UN*X code may show nasty, hard-to-find bugs. As I recall, the original K&R C book has an example of a malloc/free/realloc package that you could modify as I described above. > <mike Ross Cunniff Hewlett-Packard Colorado Language Lab cunniff@hpfcla.HP.COM
mykes@zorch.SF-Bay.ORG (Mike Schwartz) (01/11/91)
In article <8135@ucdavis.ucdavis.edu> zerkle@iris.ucdavis.edu (Dan Zerkle) writes: >I recently wrote a vector graphics package that had to allocate and >de-allocate huge amounts of small structures with malloc. I noticed >that it seemed to be running awfully slowly for some reason. When I >wrote my own memory manager instead, the program ran three times >faster. People running similar stuff on Unix (for the same class) >noticed that their programs didn't spend a lot of time on memory >management (according to the profiler). > >So: Why does the Amiga spend so much time fooling around with memory >management? Is the behavior I noted typical? > >Also, this same program's memory manager would allocate a large chunk >of memory at the beginning of the program (and in the middle, >actually), but I never bothered to de-allocate the memory before >exiting. I never noticed any problems with this, and the status line >showed as much memory before execution as after. That doesn't mean >that there wasn't a potential for problems. Does anybody know about >this? Was I doing a bad thing? Should I explicitly de-allocate the >memory before exiting, or just count on "the system" to take care of >it? > >If it matters: A3000 under 2.02, Aztec C 5.0d. > > Dan Zerkle zerkle@iris.eecs.ucdavis.edu (916) 754-0240 > Amiga... Because life is too short for boring computers. I can't answer the first question, but if there are a lot of "little" allocated chunks of memory, your program is certainly spending a lot of CPU time calling free(). Under Manx, the malloc() and free() routines are their own "glue" routines wrapped around the Amiga memory manager. One feature of these, as well as all the other routines that look like the ones on Unix, is that the exit() routine in the Manx library is smart enough to clean up for you when you exit. This means you can exit() with memory allocated, files openned, etc., and exit() will clean up for you. On the other hand, if you call AllocMem() or Open(), YOU will have to clean up or you WILL see a memory leak (less memory available after you run and exit). Cheers Mykes