dokan-dev / dokany

User mode file system library for windows with FUSE Wrapper
http://dokan-dev.github.io
5.14k stars 656 forks source link

Possibility to increase thread count & change DOKAN_OPTION_ALLOW_IPC_BATCHING? (FUSE) #1202

Open algj opened 4 months ago

algj commented 4 months ago

Environment

Check List

Description

I have been experimenting with the FUSE wrapper, but I got stuck with 2 threads. Is there a way to increase the amount of threads or spawn more threads without recompiling Dokany? On Linux, FUSE is a lot faster when dealing with multiple high latency reads, because it doesn't block IO, that's why I think min thread count should be increased, or at least customizable.

CHANGELOG: DOKAN_OPTIONS.ThreadCount was replaced by DOKAN_OPTIONS.SingleThread since the library now uses a thread pool that allocates workers depending on workload and the available resources.

I assume this was possible before, but now it depends on the CPU thread count:

https://github.com/dokan-dev/dokany/blob/415ac366eaa7a257ceb217e79dab9f37fadc7d33/dokan/dokan.c#L791-L798

I'd suggest adding a way of changing thread count in Dokany & FUSE.

Liryna commented 4 months ago

Hi @algj , Have you tried DOKAN_OPTION_ALLOW_IPC_BATCHING ? There is no FUSE option (yet) but if you could force it and see if it helps your case. Increasing main pull thread count is a limited solution that does not scale well with increase of IO activity.

algj commented 4 months ago

Oh! Thank you @Liryna! This is exactly what I was looking for! Unfortunately (from my understanding) you cannot change it without recompiling Dokany. There should be a way to change this option somehow (possibly thread count too if we're at it)

I hope someone makes a PR regarding changing this option easily... :slightly_smiling_face:

LTRData commented 4 months ago

No, the DOKAN_OPTIONS_* flags can be set in Options field in DOKAN_OPTIONS structure when mounting a new file system. It does not need recompiling driver or library.

Liryna commented 4 months ago

The problem is that those DOKAN_OPTIONS_* are not directly available for FUSE, they need to be wrapped for the FUSE interface. See here for DOKAN_OPTION_MOUNT_MANAGER

algj commented 4 months ago

I'm a little confused... I don't mind the source code having both Dokany & FUSE code, but how does one do that?

LTRData commented 4 months ago

I'm a little confused... I don't mind the source code having both Dokany & FUSE code, but how does one do that?

The problem here was apparently that if you create a native Dokany implementation, this is very easy to set from your implementation by setting a flag in the options structure when mounting a new file system.

If on the other hand you implement a file system using the Fuse emulation layer on top of Dokany, this option is hidden in the emulation layer and not exposed to your implementation.

algj commented 4 months ago

Oh my!!! Thank you very much @Liryna for the PR!! ❤️ I thought I'll have to do the PR myself 😅

algj commented 4 months ago

I have tried out IPC_BATCHING. There is a clear performance difference when I did my tests (it's slower by a few ms consistently), but for some reason it still sticks to 2 threads...? I did the same tests on Linux too, it was definitely handling concurrent reads/writes on Linux much better. I'm not sure if I'm misunderstanding something, I thought it's supposed to spawn new threads when there's a few of concurrent reads instead of blocking it all.

algj commented 4 months ago

Also, I think that ThreadCount should be added back. I guess SingleThread option could be removed, but that would break some things.

ThreadCount = 0, library decides what thread count to use ThreadCount = 1, single threaded ThreadCount >= 2, multi thread, user defines how many threads application should use

Liryna commented 4 months ago

Looks like the IPC_BATCHING option was not correctly set in the library https://github.com/dokan-dev/dokany/commit/aef92bcf23c0dea150e7864a4ef81984325fd6a5 :( (The CI tests seems to fail, I will need to look at that https://ci.appveyor.com/project/Maxhy/dokany/builds/49214019 )

Regarding ThreadCount, I don't think that's a good idea as like I said before, it does not scale correctly. Right now the best performance-wise thread count is allocated and for slow IO we need to use the thread pool.

cowboy823 commented 2 weeks ago

Hello Liryna. I have same issue with algj. I'm developing a web drive using memfs and ssh/ftp. This allows users to use some directories on the FTP server as if they were on a local drive. In this case I'm doing multi-thread process since there is the transmission delay(or latency) between the server and user sides in the network . So I have resolved the CreateFile, FindFile, WriteFile functions in multi-threading technical but not ReadFile function. Dokan seems to handle the read requests in serial(i.e. single thread). As above, I compile the dokan to have the mainPullThreadCount = 16 and tested read operation but no clear performance difference and seems to assign a thread per a file. So I can't speed up read operation(downloading). How can I solve this problem?

Liryna commented 2 weeks ago

Note: This issue only affects computers with limited number of threads as dokan set the optimal number of threads based on the hardware.

If the application (notepad, etc) that issue Create / Readfile sequentially, dokan will receive them as it. If the app issue multiple async or multi-thread reads, dokan will send multiple reads request to memfs. Your issue might be that each read are slow to execute due to network access ? Then you will need cache and precaching logic to improve the access of the data so that they are available when the read request comes in.

cowboy823 commented 2 weeks ago

Thanks for your reply. I'm going to process the read for a file in multi-thread. this is possible in dokan?

Liryna commented 2 weeks ago

Yes, memfs or the filesystem implementation can do anything it wants