English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 08 October 2023, 19:20   #1
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
Is it possible to reduce an AllocMem() chunk?

I need to allocate a block of memory with AllocMem() in asm, then do some stuff, then later halve the allocation size. How would I do this? Kind of like realloc() in C. I need to do it like this to save memory, instead of having two buffers at the same time (N*2 and N in length).

Comments like "Write better code" will be ignored.
8bitbubsy is offline  
Old 08 October 2023, 19:34   #2
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
AlllocMem() full size, Forbid(), FreeMem(), 2x AllocAbs(), Permit() perhaps?
a/b is online now  
Old 08 October 2023, 19:36   #3
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
Yet, your last answer is the correct one. Exec has no support for doing so, and any attempt to try will be caught be the usual crowd of debugging tools such as WipeOut or MuGA and will be reported as a bug.

One of the troubles is that exec internally aligns and rounds memory sizes, thus you do not do what exactly you release on FreeMem. Another probllem is that you do not know whether FreeMem or AllocMem has been replaced by some custom allocators and how they handle a siutation that is beyond the specification of exec.

Thus - yes - you must release exactly the memory you allocated, with the same pointer and the same size.
Thomas Richter is offline  
Old 08 October 2023, 19:36   #4
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
Quote:
Originally Posted by a/b View Post
AlllocMem() full size, Forbid(), FreeMem(), 2x AllocAbs(), Permit() perhaps?
While that gets you the memory you requested, it will also corrupt the contents of the buffer. Thus - no.
Thomas Richter is offline  
Old 08 October 2023, 19:47   #5
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
What a shame... Oh well.
8bitbubsy is offline  
Old 08 October 2023, 20:11   #6
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
If the larger buffer (2*N size) doesn't have to be continuous (is it a static array of some sort, or something else?) it's still doable with some extra padding at the right places...
Or if it's feasible to use indirection, array of pointers, while having the actual data split in as many chunks as you want. There are ways to organize your data, but hard to tell if it's a blackbox...
a/b is online now  
Old 08 October 2023, 20:19   #7
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
It's a continuous sample data buffer. Basically I do 4-voice 16-bit resampling+mixing to the buffer, then I scan the peak for 8-bit normalization lateron. This is for ProTracker 2.3F, which runs on even a stock Amiga 500. Samples can be up to 128kB long, so I need to use as few buffers as possible here.

Right now I first do a dummy resampler+mix loop without interpolation just to get the peak value for mixing, then later I mix up to four voices w/ linear interpolation and scale the result with the peak value (normalization) before storing it as an 8-bit value. This is not 100% correct, because the linear interpolation in the actual mixing stage will slightly affect the gain. I don't want to do interpolation in the scan process, as that makes it MUCH slower.

If I could halve the memory, I'd just first do the mixing to a 16-bit buffer while scan for the peak at the same time, then do the normalization stage and reduce the memory frootprint. It would get the most accurate normalization result.
8bitbubsy is offline  
Old 09 October 2023, 09:28   #8
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Depending how your loops are made, it may be possible to allocate two 16-bit buffers instead of one.
Then, do only half of the work in buffer1 (by halving the data size, rounded up).
Inject the peak value you get as input for doing the second half in buffer2.
Then do the normalization stage in two steps too, only using buffer1 as output.
Free buffer2, and you're done.
meynaf is offline  
Old 09 October 2023, 11:19   #9
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
That would actually work, but I just thought more about this... The current method (very slow) needs half of the memory than the faster method (mix+peak-scan in one go). I decided to just copy the main mixer for the peak scan instead, even though it's super slow for 128kB samples on an A500.
8bitbubsy is offline  
Old 09 October 2023, 13:21   #10
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
Hm, seems like the sampler code in ProTracker actually frees up the memory it didn't use over time by aligning the remainder to a multiple of 8, then subtracting that from the alloc'd length and also adding it to the memory pointer before calling FreeMem. I don't think this has ever had problems, and this has been part of the PT code since forever.

But since this is not good at all, I guess this needs some rewriting as well?
8bitbubsy is offline  
Old 09 October 2023, 14:13   #11
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 3,304
On the other hand I asked myself who would use Protracker on an A500 with 512kb chipram only nowadays? I think this configuration was already 30 years ago a seldom thing for music making. I used Protracker a lot back then and I can remember that with 512kb chip + 512kb slow the 512kb chipram weren't enough to load some larger mods (something about 300-400kb) into ram.

How many stock A500 users do you need/want to support?
daxb is offline  
Old 09 October 2023, 14:14   #12
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
Yeah I get your point, but I still don't see a reason to waste more memory than needed when samples can be as big as 128kB already.
8bitbubsy is offline  
Old 09 October 2023, 14:46   #13
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by 8bitbubsy View Post
Hm, seems like the sampler code in ProTracker actually frees up the memory it didn't use over time by aligning the remainder to a multiple of 8, then subtracting that from the alloc'd length and also adding it to the memory pointer before calling FreeMem. I don't think this has ever had problems, and this has been part of the PT code since forever.

But since this is not good at all, I guess this needs some rewriting as well?
Freeing part of a block has always worked fine in the past but is considered a bad practice and might be reported by some memory watch tools.
Not that i'd personnally recommend to avoid it, it's not like if we had a proper realloc system call.
meynaf is offline  
Old 09 October 2023, 15:49   #14
8bitbubsy
Registered User
 
8bitbubsy's Avatar
 
Join Date: Sep 2009
Location: Norway
Posts: 1,711
Alright, I'll keep that old code then. I don't know how to improve it anyway.
8bitbubsy is offline  
Old 09 October 2023, 19:45   #15
NorthWay
Registered User
 
Join Date: May 2013
Location: Grimstad / Norway
Posts: 839
Suggestion(slightly dodgy):
Code:
Forbid()
A=AllocMem(SIZE/2)
B=AllocMem(SIZE/2)
Check if they are sequentially placed in memory. Yes, this is not a guarantee of anything. The address of the end of first alloc should not deviate more than 8 bytes from the start of the second. 0 bytes apart would be preferable if you allocate something a multiple of 8 bytes.
Permit()
or perhaps more correct would be something like
Code:
Forbid()
A=AllocMem(X)
FreeMem(A,X)
B=AllocAbs(A,X/2);
C=AllocAbs(A+X/2,X/2);
Permit()
Make sure your allocation uses a multiple of 2^N (standard OS uses 8 if there are no 3rd-party patches) and test the return values. Fall back to the original code if something fails. Clean up any partial allocs.
Basically, if you know the size then make two allocs before you fill it with data, and then you know you can treat is as one and later free half of it. Still, with debug tools the logic might not hold, but then chances are memory use it not much of a worry.
NorthWay is offline  
Old 10 October 2023, 11:59   #16
Rotschi
Registered User
 
Join Date: Apr 2023
Location: "Hamcastle"
Posts: 20
Quote:
Originally Posted by Thomas Richter View Post
While that gets you the memory you requested, it will also corrupt the contents of the buffer. Thus - no.
Just out of curiosity (and curiosity killed the cat :-) ) ... what does that mean and how would it look like / manifest?
Rotschi is offline  
Old 10 October 2023, 14:00   #17
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Rotschi View Post
Just out of curiosity (and curiosity killed the cat :-) ) ... what does that mean and how would it look like / manifest?
The exec.library memory management functions can only account for memory in portions which are a multiple of 8 bytes in size. If you ask for a size which is not a multiple of 8, Allocate() will round it up for you.

The old trick of calling Forbid(), mem = AllocMem(size, ...), FreeMem(mem, size), mem1 = AllocAbs(mem, size/2), mem2 = AllocAbs(mem + size/2, size/2), Permit() may land you in hot water. AllocAbs() might even pull a recoverable Alert.
Olaf Barthel is offline  
Old 10 October 2023, 14:11   #18
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by 8bitbubsy View Post
Yeah I get your point, but I still don't see a reason to waste more memory than needed when samples can be as big as 128kB already.
How much memory is left when the program is running and doing what it was designed to? It's been a very long time since I developed software for the humble Amiga 500. Why does it matter how the allocated memory is aligned in a particular manner?
Olaf Barthel is offline  
Old 10 October 2023, 14:49   #19
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by Olaf Barthel View Post
AllocAbs() might even pull a recoverable Alert.
Why would it ? As long as memory lists are fine, the worse thing it can do is to fail just like any other memory allocation.
meynaf is offline  
Old 10 October 2023, 15:30   #20
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
Quote:
Originally Posted by Rotschi View Post
Just out of curiosity (and curiosity killed the cat :-) ) ... what does that mean and how would it look like / manifest?
Exec is tracking free and allocated chunks with linked lists. Free chunks have an 8-byte header at the start, and allocated chunks at the end.
When you FreeMem() the big chunk, exec will nuke first 8 bytes of your data (chunk becomes free and gets a header). Then, when you AllocAbs() the first small chunk it will nuke 8 bytes "in the middle".
For example, let's have a 32-byte chunk split into two 16-byte absolute chunks. Memory layout is (m=yours, *=yours but nuked, p=exec private):
Code:
0       8       16      24      32
********mmmmmmmmppppppppmmmmmmmmpppppppp
old hdr         hdr for +0      hdr for +16
I haven't messed around with absolute allocations... and this makes me wonder, why is exec allowing me to AllocAbs() at +16 because that address is used for its private data?

One idea is to backup/restore some data, but the header in the middle has to be valid at all times I'd guess, in case you do a flush and all the memory lists get validated. So, no go...
Address/size 8-byte alignment is generally easy to work around, though.
a/b is online now  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
IFF ANIM Chunk structure - DPPS and DPXT Steffest Graphics 0 06 July 2023 14:56
Chunk True Color 4 pixels remz Coders. Asm / Hardware 31 08 June 2022 13:04
hdf - ways to reduce filesize Nova support.WinUAE 8 22 December 2018 02:51
Reduce size of an IFF image? BarryB support.Apps 18 19 September 2015 03:54
How can I reduce the number of reboots on start-up? keropi support.Apps 2 08 December 2005 13:19

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 23:19.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.11133 seconds with 15 queries