interesting tests and interesting discussion!
I think that I could provide some technical background to the different memory allocation mechanisms in memory disk drivers. It basically gets down to the different memory allocation functions available to Windows kernel mode drivers and their pros and cons for various usage cases.
ExAllocatePool and related functions.These functions allocate memory from the kernel allocation pools. There is paged pool and non-paged pool, indicating whether allocated memory can be used in "non-pageable" paths in the driver, such as in interrupts routines, disk swapping requests etc. The pools are intended for small(ish) allocations, such as data structures etc needed in the drivers. Pool spaces are restricted by the kernel, especially in 32 bit Windows versions.
These pool function are frequently used in sample source code of "my first ramdisk driver" type. They tend to be quick and reliable for small ramdisks because they can carry out the entire I/O request within the context of the calling process, something which is otherwise very uncommon for any kind of disk driver, virtual or not.
This allocation method is not used in ImDisk.
MmMapIoSpace.This function directly maps physical addresses for usage within system virtual address space. There is no allocation logic, the calling driver needs to know in some other way that it is safe to use the addresses it maps. If another component uses the same memory, data corruption is likely to happen.
This memory access method is used in some ramdisk drivers to allocate physical memory beyond the point that Windows allows access to, for example above 4 GB or 32 bit Windows XP. The users of such driver need to understand that they cannot use two drivers, using this memory access method, at the same system simultaneously.
This allocation method is not used in ImDisk. However, there have been thoughts and ideas about developing a driver similar to awealloc that could access memory in this way.
MmAllocatePagesForMdl and related functions.This function allocates physical, non-pageable, memory address ranges. If AWE is used in Windows, it can allocate beyond 4 GB on 32 bit systems, if Windows license allows it. The allocated memory is not immediately available in the system address space. To access the allocated memory, a driver needs to map needed parts into virtual address space. This requires a "page-access" logic in the driver code, which in the case of awealloc is implemented using 2 MB block mapping. Therefore, with awealloc, 2 MB of allocated memory is mapped into virtual address space at any time. If the application or filesystem requests I/O to a place within the same 2 MB as last I/O request, no remapping is necessary. This gives some overhead to carrying out I/O requests to very random areas, which seems to be common for example with NTFS file system and less frequent with FATxx/exFAT.
ZwAllocateVirtualMemory (or ZwCreateSection/ZwMapViewOfSection without a file handle)These two allocation methods allocate an address range in virtual address space. They are pretty "high-level" and correspond directly to
VirtualAlloc (or using
MapViewOfFile/
CreateFileMapping without a file handle) in user mode applications. This is the method used when you create a virtual memory backed virtual disk directly in ImDisk, without using awealloc. The implementation in ImDisk is such that the entire memory needed is allocated in one single block. This means that the space necessary for the entire vm disk needs to be available directly within kernel address space. Especially on 32 bit versions of Windows, this part limits the use for this allocation method for anything but rather small virtual disks. If a large amount of kernel address space is allocated, necessary allocations in other drivers may fail and cause system instability.
On the other hand, this allocation method provides a very simple usage interface to the driver. All page committing, mapping etc is handled by the kernel in background and transparent to the driver. The driver just sees a large memory block that it can assume is directly accessible, even if the pages it is about to access are paged out to disk or not even physically allocated yet.
This allocation method was implemented in ImDisk for use with smaller allocations. I used to use ImDisk for virtual floppy disks in this way, or for copying small(ish) .iso images to memory when installing applications etc. This proved to be, back then, a good solution because it was not necessary to keep the memory disk contents in physical memory at all times (it is pretty okay for a virtual floppy disk to be swapped out to pagefile when not needed). The goal was more to break connection with any physical image file that could be on some removable disk or network location.
Summary.The various memory access/allocation methods are good for different things. It is quite expected that measured performance will differ a lot. But my general opinion is that for memory backed virtual disks, there is no good reason to use internal ImDisk allocation for disks larger than, say 100-200 MB or so. Awealloc should really be used instead. I have also thought about an easier way to use awealloc from GUI. You could type \\.\awealloc in the filename box and provide a disk size in the next box, but it is not very "self-explaining".
I have pretty much stopped maintaining the Control Panel applet though. It is hopelessly outdated for many reasons. Not only graphically, but it does not fit into the UAC logic in Vista and above pretty well either. So, I was kind of hoping that someone could develop a more modern GUI, using the nowadays quite powerful API. It seems that some people have done that. But as far as I know, none of them have been released for free.