> Hi all,
I am performing a scatter gather DMA from FPGA to PC on windows XP, x86
architecture. The FPGA is continuously sending video data and I am
allocating 8kb of buffer from my driver end. Once I get 8kb chunk from
FPGA, I am transferring the data into a file using fwrite (
fwrite(buffer, 8k , 1 , file pointer) in append mode ) and I repeat this
8kb DMA transfer + file writes continuously.
I am not aware of any hard drive that can guarantee the write happens
within the time span you give. Even with a cache, there can be a problem.
One issue here is that “many” is a meaningless word. Some cultures count
“1, 2, 3, many”, and some of use think that “many” doesn’t lose meaning
until it exceeds tens of millions. So the “many” could be the point where
you filled up the disk drive cache, and it now has to start delaying while
it writes the cached data to the magnetic surface. Have a quantity of
“many” would help.
Also, fwrite is a lousy way to handle it; the C library does a lot of
internal buffering to handle transport. Just go for the raw WriteFile.
Then, you should be handling it asynchronously, so the requests can queue
in the kernel. The important thing is that you get control back quickly;
when it actually completes is not nearly as important as getting back
fast. When I was confronted by a similar performance problem, I solved it
by queuing up a bunch of ReadFile requests to the device, so with 50 I was
able to keep it within its realtime window to read data. You should
expect a write to take between 5000 and 10000 microseconds (typical disk
delays including rotational delays and small-step seek times; sometimes
+/-1 cylinder is very fast, 2ms for some disks I looked at; sometimes a
larger range can also be fast, such as up to +/-8 or similar. Oh, yes, if
your disk is badly fragmented, you’re screwed already)
Also, since your app is a passive-level thread, it is subject to
preemption by other threads of higher priority, such as the file system’s
writeback thread(s), so you really need to expect that when your 8K buffer
is ready, your app may not be. Which is why the queue of ReadFiles helps
a lot.
A warning, though: according to the experts on this NG, the order in which
asynchronous requests are sent back to the app is not necessarily the
order in which the driver completed them. Therefore, you will need to put
a “sequence number” in as a “packet header” (32 bits would be great), and
you may need to “reassemble” packets. Everything has a price.
For time-sensitive high-performance devices, synchronous I/O is usually
the kiss of death; you are at the mercy of the app-to-kernel transition
loop, and if you place another synchronous I/O in this path, forget it.
So you do a read from your device, and you must immediatly re-queue the
read (to a different buffer; you need a buffer ring with as many buffers
as you have concurrent ReadFiles), THEN do the write, asynchronously. And
you are STILL at the mercy of the scheduler, so it pays to have a lot of
ReadFiles down there to keep up with the data rate. So your first plan
should be to ditch all synchronous I/O to the device, and all synchronous
I/O to the disk.
joe
You have not said what the incoming data rate is. How much data does 8K
represent? How many 8K buffers are required to get a single frame in?
Maybe you should be thinking of your driver in terms of being able to
buffer an entire frame, where a frame is some large multiple of 8K.
You did not tell us what priority boost you used when you completed the
request. It might be easier to suggest answers if we had the necessary
information.
If you are running on Vista or later, look into the Multimedia Scheduling
Service (MMSC is at least a substring of the acronym, which I no longer
recall). This allows you to run a user level thread in a “normal” process
in the “time sensitive” priority ranges, 16…26 (the service itself runs a
priority 27, so it blocks you from any higher priority).
Problem regarding performance:
- For the performance to be fine, DMA of 8kb + file writes should happen
within 250 microseconds. Ideally dma of 8kb takes around 50 microseconds
and file writes around 20 microseconds for every 8kb. This will be ok, but
sometime after many such 8kb transfers and file writes, the file write
(fwrite) takes upto 1000 - 10000 microseconds to write 8kb (instead of 20
microseconds) suddenly, due to which I lose my data coming from the FPGA
continuously. I really can’t control the data from the FPGA end since it
is a high performance video data coming at a faster rate.
So I would like to know the reason why fwrite takes so much time
sometimes? Is there a way I can handle this file write issue?
Thanks
NTDEV is sponsored by OSR
OSR is HIRING!! See http://www.osr.com/careers
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer