6

I am writing to USB disk from a lowest priority thread, using chunked buffer writing and still, from time to time the system in overall lags on this operation. If I disable writing to disk only, everything works fine. I can't use Windows file operations API calls, only C write. So I thought maybe there is a WinAPI function to turn on/off USB disk write caching which I could use in conjunction with FlushBuffers or similar alternatives? The number of drives for operations is undefined.

Ideally I would like to never be lagging using write call and the caching, if it will be performed transparently is ok too.

EDIT: would _O_SEQUENTIAL flag on write only operations be of any use here?

10
  • I don't get it. You want to never block yet you're using a super-low thread priority? That doesn't make any sense. What is your outer problem exactly? Commented Mar 27, 2012 at 21:10
  • @david-schwartz write operation gives a overall system lag at some frequency. I dont care about blocking in the thread, I meant system lag..., will correct question
    – Ulterior
    Commented Mar 27, 2012 at 21:12
  • Do you have any more details on what the issue is? Is it, for example, that the volume of writes is pushing other information out of cache? If you know what you're doing, you can do non-temporal writes that bypass the disk cache. Commented Mar 27, 2012 at 21:17
  • 1
    Seems Windows have some fundamental problems with disk access. Just reading data from USB volume with bad sectors causes the entire system to stall violently (Windows 7 64-bit)
    – Sergey K.
    Commented May 22, 2012 at 13:34
  • 1
    Hmm, the symptoms described remind me of this: stackoverflow.com/questions/7856251/… ... I tend to agree with Sergey, Windows has issues :( Commented May 23, 2012 at 5:26

4 Answers 4

4

Try to reduce I/O priority for the thread. See this article: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686277(v=vs.85).aspx In particular use THREAD_MODE_BACKGROUND_BEGIN for your IO thread. Warning: this doesn't work in Windows XP

8
  • So if you already reduced priority of IO thread down to minimum I suppose you don't care much about IO speed (it just have to happen). So I would suggest then to use approach that is similar to Windows Defragmenter - check current disk IO levels and don't do anything unless they are at minimum - I believe you feel lags when USB IO blocks main HDD IO
    – Alex Z
    Commented Mar 27, 2012 at 21:31
  • hmm, this could work. Do you have any more info on that? I will check it out, for sure
    – Ulterior
    Commented Mar 27, 2012 at 21:36
  • It's all about Performance Counters (msdn.microsoft.com/en-us/library/windows/desktop/…), but I never actually accessed them from WinAPI
    – Alex Z
    Commented Mar 27, 2012 at 21:38
  • Be careful, THREAD_MODE_BACKGROUND_BEGIN for IO is broken on Windows Vista. Commented May 22, 2012 at 7:55
  • Mahmound, could you be more specific? Never heard of this yet
    – Alex Z
    Commented May 22, 2012 at 12:24
3

The thread priority won't affect the delay that happens in the process of writing the media, because it's done in the kernel mode by the file system/disk drivers that don't pay attention to the priority of the calling thread.

You might try to use "T" flag (_O_SHORTLIVED) and flush the buffers at the end of the operation, also try to decrease the buffer size.

2

There are different types of data transfer for USB, for data there are 3: 1.Bulk Transfer, 2.Isochronous Transfer, and 3.Interrupt Transfer.

  1. Bulk Transfers Provides:

    Used to transfer large bursty data.
    Error detection via CRC, with guarantee of delivery.
    No guarantee of bandwidth or minimum latency.
    Stream Pipe - Unidirectional
    Full & high speed modes only.
    

    Bulk transfer is good for data that does not require delivery in a guaranteed amount of time The USB host controller gives a lower priority to bulk transfer than the other types of transfer.

  2. Isochronous Transfers Provides:

    Guaranteed access to USB bandwidth.
    Bounded latency.
    Stream Pipe - Unidirectional
    Error detection via CRC, but no retry or guarantee of delivery.
    Full & high speed modes only.
    No data toggling.
    

    Isochronous transfers occur continuously and periodically. They typically contain time sensitive information, such as an audio or video stream. If there were a delay or retry of data in an audio stream, then you would expect some erratic audio containing glitches. The beat may no longer be in sync. However if a packet or frame was dropped every now and again, it is less likely to be noticed by the listener.

  3. Interrupt Transfers Provides:

    Guaranteed Latency
    Stream Pipe - Unidirectional
    Error detection and next period retry.
    

    Interrupt transfers are typically non-periodic, small device "initiated" communication requiring bounded latency. An Interrupt request is queued by the device until the host polls the USB device asking for data.

From the above, it seems that you want a Guaranteed Latency, so you should use Isochronous mode. There are some libraries that you can use like libusb, or you can read more in msdn

4
  • 1
    The USB device, the disk, decides what transfer modes it handles. If it does not do interrupt mode, then it doesn't. I don't think there is any USB drive that does anything other than BULK transfers. Commented May 24, 2012 at 12:11
  • well, I strongly recommend to read more before you downvote and "I don't think ..." is not an acceptable reason to throw away a potential answer that may actually help someone. Getting back to subject, it is possible to transfer data in interrupt and isochronous if you want to know how you can read this article in msdn. you can read more here. and technical details are in this article. Commented May 26, 2012 at 7:12
  • OP is asking for his IO to not block other IO, don't believe he wants guaranteed latency, the opposite actually. Commented May 26, 2012 at 23:02
  • @Showang You: Of course data can be transferred by interrupt and isochrnous transfers. That is not my point. It's just that the USB Mass Storage Class specifies bulk transfers (unless you are dealing with floppy disks, apparently). As the question mentions "USB disk" I think it is fair to assume that it involves USB MSC, and thus only BULK transfers are relevant. Hope this clarifies the issue. Just for reference: I have implemented the USB MSC for a device, so I have a fair understanding of how USB transfers work. Commented May 28, 2012 at 9:23
0

To find out what is letting your system hang you first need to drill down to the Windows hang. What was Windows doing while you did experience the hang?

To find this out you can take a kernel dump. How to get and analyze a Kernel Dump read here.

Depending on the findings you get there you then need to decide if there is anything under your control you can do about. Since you are using a third party library to to the writing there is little you can do except to set the IO priority, thread priority on thread or process level. If the library you were given links against a specific CRT you could try to build your own customized version of it to e.g. flush after every write to prevent write combining by the OS to write only data in big chunks back to disc.

Edit1

Your best bet would be to flush the device after every write. This could force the OS to flush any pending data and write the current pending writes to disc without caching the writes up to certain amount.

The second best thing would be to simply wait after each write to give the OS the chance to write pending changes though small back to disc after a certain time interval.

If you are deeper into performance you should try out XPerf which has a nice GUI and shows you even the call stack where your process did hang. The Windows Team and many other teams at MS use this tool to troubleshoot hang experiences. The latest edition with many more features comes with the Windows 8 SDK. But beware that Xperf only works on OS > Vista.

Not the answer you're looking for? Browse other questions tagged or ask your own question.