Logged in as Guest   Mon, Jun. 23rd, 1:03 PM.      
Visitor Map
Recent Entries:
What I've Been Up To
Debugging Windows Mobile/WinCE Applications Without ActiveSync
LinkedIn
I'm BACK!!!!!!
Code Monkey
Cool 3D Code Snippet From My Former Life
YouTube: The Revival of the Internet Time Killer
WhereMate Released
Palmasaurus Released As Freeware
VM-Plus Beta

Archive:
May - 2008
April - 2008
March - 2008
October - 2007
August - 2007
July - 2007
June - 2007
May - 2007
April - 2007
December - 2006
November - 2006
September - 2006
August - 2006
July - 2006
March - 2006
February - 2006
January - 2006
December - 2005
November - 2005
October - 2005
September - 2005
August - 2005
July - 2005
June - 2005
May - 2005
April - 2005
February - 2005
January - 2005
December - 2004
November - 2004
October - 2004
September - 2004
August - 2004
July - 2004
June - 2004
May - 2004
April - 2004
March - 2004

The NVFS DBCache
Well, I had hoped to write more on NVFS after I had a lot more to say, however, I have received several emails (including one from Ben) that have a common misunderstanding about the NVFS implementations on the Tungsten T5 and the Treo 650, and I figured it might be helpful to try and clear it up.
By far, the issue that is most misunderstood is the DBCache that the devices utilize, and how it is flushed once it is full. Before going too quickly into it, I should layout a little backstory on the NVFS implementation (especially regarding what is known as the DBCache.)
Let's start with the physical layout of the T5. According to the docs, the memory footprint on the T5 looks like this:
RAM: 32MB total
16MB – OS image copied from flash at boot
10MB – storage heap cache
6MB – dynamic heap

FLASH: 256MB total
160MB – VFS flash drive
55MB – flash-based storage heap
41MB – compressed OS image, hidden storage space, 
       and blocks for remapping bad sectors

As you can see, there is a 10 MB storage heap cache. According to the SDK, while an application is running, any active/open databases are allocated out of this 10 MB. This allocation occurs in almost exactly the same way that it is allocated on pre-NVFS devices. (This 10 MB is what is commonly referred to as the DBCache, and I will henceforth refer to it as such.)
Also according to the SDK, there are certain times when that DBCache is "flushed" to the VFS Flash drive for permanent storage:
    1. Application exit 
    2. Power cycle 
    3. Database closing 
    4. Explicity by the user with the DmSyncDatabase function

The next time that a database is opened, it is copied from the VFS drive to the DBCache for quicker usage. To better understand NVFS, you have to understand that the VFS memory is what is known as NAND memory. One of the implications of NAND memory is that it is quick to read, but slow to write. , and if you do have to write to NAND, it's better to do it in big chunks. (For a really good explanation of NAND RAM, see Ed Nisley's article in the March 2005 issue of Dr. Dobb's Journal). Because of this limitation, palmOne's NVFS implementation is optimized to minimize the number of writes that occur to the NAND memory.
This of course, is where the DBCache comes into play: to minimize the number of writes to NAND. To date, this information has been understood by all of the people that have written me about my previous T5 NVFS article. The part that has not been understood is the runtime usage of the DBCache. As pointed out earlier, it is only 10 MB in size. For normal things, that is a fairly acceptable size. However, in my sample loop, I was allocating approximately 40 MB worth of data. If the OS only flushed the DBCache during those 4 stated conditions above, no program could ever allocate a DB at runtime that was more than 10 MB without having to either close the database or explicitly call DmSyncDatabase. For a 256 MB device, that would be quite a crippling limitation! Fortunately, there is one more condition when the devices flush the DBCache: when the DBCache itself becomes full. It is slightly buried in a very short paragraph in the SDK, but the docs do mention that when the DBCache becomes full, the OS will "intelligently purge" it. If you take the code from my earlier article and run it on the T5, you can actually see this in action. Once the allocations hit around 8 MB, the T5 starts crawling. This slow, chunking slowdown is occuring as the OS flushes the DBCache, and it is paying a penalty for the slow write speed of the NAND RAM. I can't say exactly what algoritm the T5 and the 650 use to do the purging, but I have determined that it takes a fairly minimalist approach. As my loop keeps allocating, the DBCache fills and begins flushing, and it seems to keep having to flush until it is finished. Because of this, I suspect that it is only flushing enough memory for the requested allocation. Perhaps it should flush more, perhaps not; it probably depends on what you are doing. My biggest complaint is that there isn't any exposed functionality to perform this flushing from the application's perspective. If you are trying to squeeze every last bit of performance out of your application and you're running on an NVFS device, you're at the mercy of the OS in those regards. The only function that is given to you as a developer is DmSyncDatabase, but that just writes it to the VFS RAM; it doesn't empty ANYTHING out of the DBCache. Ugh.
That's about it for my explanation of the DBCache. I hope that it helps someone. It certainly cost me a lot of blood sweat and mostly tears to figure it out. As always, please let me know if you think I've gotten anything wrong.

-Jon
Submitted by bosshogg on Thursday the 24th of February 2005, at 09:07 pm