Very interesting post btw. Thanks.
Very interesting post btw. Thanks.
So in the storage business everything used to be done on the highest performance, most reliable drives. Typically those were 15K RPM Fibre Channel drives which cost 8x the price of an equivalent SATA drive [1]. In 2003 NetApp created the 'NearStore' line which was filers that used SATA drives. The idea was that tape was way to slow, you could put stuff on SATA drives and for low duty cycles get to it a lot faster, SATA drives were 'nearline' storage which was defined to be "about 99.8% available." This was hugely better than tape but not as good as a "real" disk array. Of course what people discovered was that you could have some pretty huge data sets be reasonably accessible that way, the first folks were the oil and gas folks [2] but lots of people jumped onto the bandwagon, it was cheaper than a storage array, faster than tape.
Now lets look at flash. Most people think of flash as a disk replacement because it connects to the computer through a disk interface (even though it doesn't have disk mechanicals). So it seems like a really fast disk. My assertion though is that it isn't a fast disk, its slow memory. It is 'near line' memory. Which is to say it takes a lot longer to access something in flash than it does in memory, but its craploads faster than getting off of spinning rust.
Four years ago, I told a guy who claimed to be Intel's key flash architect that if Intel would put flash on the same side of the MMU as the processor we would completely change the way servers are built. Why? Can you imagine that you've got 200GB of address space that is already ready to go when you turn on the processor? Once you start loading page tables you read in the ones in non-volatile flash and blam all your data structures are ready to go, right now. You want to make some sort of logical computation based on the state of a 50GB data structure, and all you do is follow the pointers? The 'driver' for flash attached as memory is
var = *((var type *)(0xsome64bitaddress);
But we cannot do that because flash doesn't live on the front side bus, it lives, at best, in the PCI Express address space on the other side of the Southbridge. [3].Bottom line Solid State drives are doomed, you can't make them much denser the physics doesn't work, you don't want to waste your time going through the disk driver and I/O subsystem to get to what is essentially more memory. But as flash moves closer to the CPU its impact will become pretty impressive.
[1] This lead people like IBM to propose 'bricks' which were 8 SATA drives in a RAID or Mirrored config pretending to be a single reliable drive.
[2] One of my favorite Dave Hitz quotes: "Oil and Gas companies have an awesome compression algorithm, they can take a 600TB data set and compress it to one bit, 'oil' or 'no oil.'"
[3] Yes the new Sandy Bridge DDIO architecture helps with this. (http://www.realworldtech.com/sandy-bridge-ep/2/)
But this would require completely changing how modern operating systems work. No doubt applications developers would love it though.
disks and filesystems as a weird, separate appendage hanging off the side of a computer are conceptually a weak idea.
Once you've unified your address space - stable storage is in the same space as unstable storage, then your entire world changes. The trick then becomes, how do you represent objects (Hint: Others have already tread this ground, see AS/400).
a) data is buffered during write and that a power failure won't leave the storage in an inconsistent state b) blocks to be overwritten are reallocated and erased in background (you cannot simply overwrite a flash block before erasing it) c) the used datastructures (trees etc) are optimized for the size of the flash block d) gracefully handle block corruption
Since it should be possible to remap blocks (either because of (b) or corruption (d)) it's common to have a logical block remapping layer somewhere in the (disk) controller. At this point classical filesystem algorithms and datastructure can easily solve the remaining problems (consistency with journaling and block optimized access like on rotating disks).
Of course, there is another approach for solving (b): see http://en.wikipedia.org/wiki/Log-structured_file_system (actually, log structured filesystem technique can be used to implement the block remapping within the ssd compatibility layer which lies inside the disk controller itself, but that's a detail) or copy on write filesystems like zfs/btrfs etc (although AFAIK they rely on a disk interface which is compatible to a rotating disk).
That's to say that solid state storage is not really just persistent ram where you can apply the same datastructures and procedures you would use in core.
Future technologies might be different and trim down these differences so that you could really have huge amount of super fast word addressable random memory access, where nothing can be lost even in case of power failure. But, even assuming that this might be possible, it's possible that later there will be yet another technology with even better storage density/ cost but which will introduce back some of the complications. So, it's understandable why you want to keep some abstractions, so that you can easily replace the underlying technologies and get most of the benefits.
>You want to make some sort of logical computation based on the state of a 50GB data structure, and all you do is follow the pointers? The 'driver' for flash attached as memory is
> var = ((var type )(0xsome64bitaddress);
You don't need any changes in hardware for this, you can use memory mapped files. Main reason that today software serialise everything is interoperability. For example, old versions of Microsoft Office applications did this, modern don't.
Also read about PhantomOS.
That still triggers the OS drivers on the other end which has to go through the same complicated drivers to read blocks into RAM before mapping them into the process, so it's nowhere comparable to what he's proposing.
Flash on the main bus would mean the only thing a read would go through would be the MMU page translation, then straight to either the flash chips or the flash controller, without being bottlenecked by passing through other parts of the system.
And that bottleneck is already real - I have SSD setups at works that are pretty much maxing out the PCIe bus on those servers, and they're not even that expensive (as long as you want performance, not large amounts of storage).
Now, there are still challenges, not least that either you're still talking to a flash controller rather than directly to the flash chips, or you have to handle wear levelling etc. yourself if you want to do writes. Both have disadvantages.
Some embedded systems do talk straight to the flash chips themselves and handle the wear levelling directly - I once put Linux on a BIOS-less x86 system with flash directly on the main bus where the "bootloader" did the equivalent of a memcpy to copy the kernel into a suitable location, set up some very basic stuff and jumped to it, and where the "disk" used an FTL (flash translation layer) driver that handled wear levelling in the kernel code.
It's a nice idea, but the driver for flash needs to do much more than this. For example, blocks need to be erased before they can be re-written, and since they have a limited lifecycle blocks must also be copied around and remapped.
The latency of NAND flash will be so much more than DRAM that you'd have to use DRAM as the cache layer before the flash in which case you could just use one of those block caching schemes coupled with a PCIe SSD to get everything that is good with very little trouble at the architecture level.
Not trying to be a party pooper, but flash does not behave like random access memory at all. With RAM, you can erase/overwrite memory at any address at will. With both NAND and NOR flash, you can only update 1s to 0s or 'reset' bits to 1. But this is only done in chunks. Flash is actually called 'flash' because in the early prototypes, there was a visible flash of light when a block was reset to all 1s. This means that to erase part of a block, any data that is to preserved within this block first has to be moved away. So the controller uses a block mapper to keep the address presented on the interface the same, while actually relocating data to someplace else (a bit like the remapping that common hard drives do when a sector goes bad). To further complicate matters, there's only so many times a block can be erased — erasing causes wear. So the block mapper also incorporates a mechanism for wear leveling. This is also why you want to align your partitions to match the erasure blocks. Otherwise you'll get write amplification; you'd write to 1 block of your filesystem, but if that block straddles erasure blocks, it would cause 2 relocations.
There are filesystems in the Linux kernel that are built to do wear leveling (i think it was yaffs/ubifs), they operate on MTD devices (/dev/mtd?) that do not do their own wear leveling. If you use CF or SD cards, or USB flash drives, they'll have a controller which does the wear leveling (but they don't always do this in a sane way).
So, sure, you could get Flash to behave like RAM, but it would be through emulation, by hiding the relocation and wear leveling logic. You could propose doing this in some super-heavy special MMU and I am with you in sofar as that it could be of some benefit to eliminate some abstraction layers like ATA and avoid hitting a bus (pci, or usb on pci).
It actually reminds me a lot of old core memory (http://en.wikipedia.org/wiki/Magnetic-core_memory). In order to read core memory, you had to actually try to write to it. If the voltage changed, you guessed wrong, so you then knew the correct value.
But it would be useful to put NAND controller closer to CPU, remove block device emulation layer and let OS do wear-leveling and block allocation. We could get high-performance swap or put there specialized MTD filesystems like UBIFS.