Re: Prioritize my own app's disk access
Re: Prioritize my own app's disk access
- Subject: Re: Prioritize my own app's disk access
- From: Alastair Houghton <email@hidden>
- Date: Wed, 06 Jul 2016 10:39:56 +0100
On 5 Jul 2016, at 13:36, Jonathan Taylor <email@hidden> wrote:
>
> This is a long shot, but I thought I would ask in case an API exists to do what I want. One of the roles of my code is to record video to disk as it is received from a camera. A magnetic hard disk can normally keep up with this, but if the user is also doing other things on the computer (e.g. long file copy in the Finder) then we are unable to keep up, and accumulate an ever-increasing backlog of frames waiting to be saved. This eventually leads to running out of memory, thrashing, and an unresponsive computer. Dropping frames is not an option. In this case, the computer is a dedicated workstation running my code, so it *is* correct for me to consider my code to be the number 1 priority on the computer.
Let’s start this again, because I think the fundamental problem here is that you’re going about this the wrong way. Whether you use Cocoa or not is, I think, largely an irrelevance (I *wouldn’t* for this kind of task, but I see no fundamental reason why performance should be a problem just because you choose to e.g. use NSMutableData to manage your buffer space, *provided* you do it right).
The first thing to state is that you *can’t* write code of this type with the attitude that “dropping frames is not an option”. Fundamentally, the problem you have is that if you generate video data faster than it can be saved to disk, there is only so much video data you can buffer up before you start swapping, and if you swap you will be dead in the water --- it will kill performance to the extent that you will not be able to save data as quickly as you could before and the result will be catastrophic, with far more frames dropped than if you simply accepted that there was the possibility the machine you were on was not fast enough and would have to occasionally drop a frame.
The right way to approach this type of real time encoding problem is as follows:
1. Use statically allocated buffers (or dynamically allocated once at encoder or program startup). DO NOT dynamically allocate buffers as you generate data.
2. Knowing the rate at which you generate video data, decide on the maximum write latency you need to be able to tolerate. This (plus a bit as you need some free to encode into) will tell you the total size of buffer(s) you need.
3. *Either*
(i) Allocate a ring buffer of the size required, then interleave encoding and issuing I/O requests. You should keep track of where the as-yet-unwritten data starts in your buffer, so you know when your encoder is about to hit that point. Or
(ii) Allocate a ring *of* fixed size buffers totalling the size required; start encoding into the first one, then when finished, issue an I/O request for that buffer and continue encoding into the next one. You should keep track of which buffers are in use, so you can detect when you run out.
4. When issuing I/O requests, DO NOT use blocking I/O from the encoder thread. You want to be able to continue to fetch video from your camera and generate data *while* I/O takes place. GCD is a good option here, or you could use a separate I/O thread with a semaphore, or any other asynchronous I/O mechanism (e.g. POSIX air, libuv and so on).
5. If you find yourself running out of buffers, drop frames until buffer space is available, and display the number of frame drops to the user. This is *much* better than attempting to use dynamic buffers and then ending up swapping, which is I think what’s happening to you (having read your later e-mails).
Without knowing exactly how much video data you’re generating and what encoder you’re using (if any), it’s difficult to be any more specific, but hopefully this gives you some useful pointers.
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden