Re: Zend fast cache
| From: | Andi Gutmans | Date: | Mon, 02 Dec 2002 05:16:10 +0000 |
| Subject: | Re: Zend fast cache | ||
| References: | 1 2 3 4 5 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-91995@lists.php.net to get a copy of this message | ||
At 05:27 PM 12/1/2002 -0500, Sterling Hughes wrote:
At 07:17 PM 11/30/2002 -0500, Sterling Hughes wrote:This pool would be per-thread.hrm. :) My only question is really about sequential accesses. for the purpose of example let's pretend its just for zvals... (pool is our pool array of zval structs) ALLOC_ZVAL() -> Do we have a zval available? -> yes! -> return pool[0][0] ALLOC_ZVAL() ... -> return pool[0][1] ALLOC_ZVAL() ... -> return pool[0][2] FREE_ZVAL() -> Clear memory @ pool[0][1] ALLOC_ZVAL() -> Do we have a zval available? -> return pool[0][3] or do we return pool[0][1] The problem I see with an array approach from an api perspective issimplywhen a bucket is free'd, in order to have efficient memory usage, we'd need a second level array scan for every ALLOC_ZVAL(). Perhaps a linked list would be a better choice for this, as we canjust besmart about bucket access, and eliminate the need for a scan (could be possible I'm missing something?)I think I was misunderstood. Of course I would want a free list. Check out the objects_store code in ZE2. The idea is to have something similar. When we free allocated buckets we add them to a linked list. The linked list is inside the structure itself, i.e., when the bucket isn't used we can use its memory for the pointer to the next element. So allocation just takes the bucket out of the free list. So basically the bucket is a union between sizeof(zval) and sizeof(*) (or sizeof(int)). If it's still not clear I can explain it in a longer letter later on. Ok, i understand - you basically are doing the linked list approach, but using a two-tiered storage paradigm to avoid fragmentation? My only thought now is the dirty specifics: 1) Thread-safety: Will we have to mutex access to this cache? We shouldn't get corruption (I'd assume that on threaded environments we'd use a shared cache) if we have multiple accesses, and if we mutex, we might as well malloc().
2) Growing buffer sizes. Say we have a _really_ intensive script that does make us grow our zval/object/hashtable cache substantially, however, it is run once every blue moon. Do we after execution is finished than realloc() that huge buffer back down to a normal size? Or perhaps we should just malloc() after a certain size is reached (ok, 16k of prealloc'd stuff, if we don't have a free slot, just do uncached mallocs).We'd recreate the cache ever request. It wouldn't cost very much. By the way, I think you did misunderstand me. In my way there wouldn't be a huge buffer. We'd have X buffers. Basically my idea was a two-dimensional array: arr[0] -> buffer of size n arr[1] -> buffer of size n arr[2] -> buffer of size n arr[3] -> buffer of size n ..... And we allocate buffers as needed. Block 1*n+4 would be in arr[1] slot 5 Andi