/ Check-in [e1464930]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Shave a few cycles so that performance is better than 3.7.4 in speed tests.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e14649301138b6840e24a4bbd2cf5205c0f72409
User & Date: drh 2011-01-25 04:34:51
References
2011-01-25
18:30
Fix new compiler warnings in pcache1.c that were introduced by the recent performance enhancement patches of [e14649301138b684]. check-in: c17703ec user: drh tags: trunk
Context
2011-01-25
09:54
Fix a problem in memsubsys1.test. Modifications to test code only. check-in: 7ef3f7cb user: dan tags: trunk
04:34
Shave a few cycles so that performance is better than 3.7.4 in speed tests. check-in: e1464930 user: drh tags: trunk
2011-01-24
20:18
Modify the test_quote.c demonstration shim so that it works when SQLITE_THREADSAFE=0 is defined. check-in: b70bccca user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

   914    914     pInfo->nHeader = n;
   915    915     testcase( nPayload==pPage->maxLocal );
   916    916     testcase( nPayload==pPage->maxLocal+1 );
   917    917     if( likely(nPayload<=pPage->maxLocal) ){
   918    918       /* This is the (easy) common case where the entire payload fits
   919    919       ** on the local page.  No overflow is required.
   920    920       */
   921         -    int nSize;          /* Total size of cell content in bytes */
   922         -    nSize = nPayload + n;
          921  +    if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
   923    922       pInfo->nLocal = (u16)nPayload;
   924    923       pInfo->iOverflow = 0;
   925         -    if( (nSize & ~3)==0 ){
   926         -      nSize = 4;        /* Minimum cell size is 4 */
   927         -    }
   928         -    pInfo->nSize = (u16)nSize;
   929    924     }else{
   930    925       /* If the payload will not fit completely on the local page, we have
   931    926       ** to decide how much to store locally and how much to spill onto
   932    927       ** overflow pages.  The strategy is to minimize the amount of unused
   933    928       ** space on overflow pages while keeping the amount of local storage
   934    929       ** in between minLocal and maxLocal.
   935    930       **

Changes to src/pcache1.c.

    46     46   ** PGroup which is the pcache1.grp global variable and its mutex is
    47     47   ** SQLITE_MUTEX_STATIC_LRU.
    48     48   */
    49     49   struct PGroup {
    50     50     sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
    51     51     int nMaxPage;                  /* Sum of nMax for purgeable caches */
    52     52     int nMinPage;                  /* Sum of nMin for purgeable caches */
           53  +  int mxPinned;                  /* nMaxpage + 10 - nMinPage */
    53     54     int nCurrentPage;              /* Number of purgeable pages allocated */
    54     55     PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
    55     56   };
    56     57   
    57     58   /* Each page cache is an instance of the following object.  Every
    58     59   ** open database file (including each in-memory database and each
    59     60   ** temporary or transient database) has a single page cache which
................................................................................
    69     70     ** The PGroup mutex must be held when accessing nMax.
    70     71     */
    71     72     PGroup *pGroup;                     /* PGroup this cache belongs to */
    72     73     int szPage;                         /* Size of allocated pages in bytes */
    73     74     int bPurgeable;                     /* True if cache is purgeable */
    74     75     unsigned int nMin;                  /* Minimum number of pages reserved */
    75     76     unsigned int nMax;                  /* Configured "cache_size" value */
           77  +  unsigned int mxPinned;              /* nMax*9/10 */
    76     78   
    77     79     /* Hash table of all pages. The following variables may only be accessed
    78     80     ** when the accessor is holding the PGroup mutex.
    79     81     */
    80     82     unsigned int nRecyclable;           /* Number of pages in the LRU list */
    81     83     unsigned int nPage;                 /* Total number of pages in apHash */
    82     84     unsigned int nHash;                 /* Number of slots in apHash[] */
................................................................................
   512    514     UNUSED_PARAMETER(NotUsed);
   513    515     assert( pcache1.isInit==0 );
   514    516     memset(&pcache1, 0, sizeof(pcache1));
   515    517     if( sqlite3GlobalConfig.bCoreMutex ){
   516    518       pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
   517    519       pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
   518    520     }
          521  +  pcache1.grp.mxPinned = 10;
   519    522     pcache1.isInit = 1;
   520    523     return SQLITE_OK;
   521    524   }
   522    525   
   523    526   /*
   524    527   ** Implementation of the sqlite3_pcache.xShutdown method.
   525    528   ** Note that the static mutex allocated in xInit does 
................................................................................
   561    564   
   562    565     sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
   563    566     pCache = (PCache1 *)sqlite3_malloc(sz);
   564    567     if( pCache ){
   565    568       memset(pCache, 0, sz);
   566    569       if( separateCache ){
   567    570         pGroup = (PGroup*)&pCache[1];
          571  +      pGroup->mxPinned = 10;
   568    572       }else{
   569    573         pGroup = &pcache1_g.grp;
   570    574       }
   571    575       pCache->pGroup = pGroup;
   572    576       pCache->szPage = szPage;
   573    577       pCache->bPurgeable = (bPurgeable ? 1 : 0);
   574    578       if( bPurgeable ){
   575    579         pCache->nMin = 10;
   576    580         pcache1EnterMutex(pGroup);
   577    581         pGroup->nMinPage += pCache->nMin;
          582  +      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
   578    583         pcache1LeaveMutex(pGroup);
   579    584       }
   580    585     }
   581    586     return (sqlite3_pcache *)pCache;
   582    587   }
   583    588   
   584    589   /*
................................................................................
   588    593   */
   589    594   static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
   590    595     PCache1 *pCache = (PCache1 *)p;
   591    596     if( pCache->bPurgeable ){
   592    597       PGroup *pGroup = pCache->pGroup;
   593    598       pcache1EnterMutex(pGroup);
   594    599       pGroup->nMaxPage += (nMax - pCache->nMax);
          600  +    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
   595    601       pCache->nMax = nMax;
          602  +    pCache->mxPinned = nMax*9/10;
   596    603       pcache1EnforceMaxPage(pGroup);
   597    604       pcache1LeaveMutex(pGroup);
   598    605     }
   599    606   }
   600    607   
   601    608   /*
   602    609   ** Implementation of the sqlite3_pcache.xPagecount method. 
................................................................................
   663    670   **      proceed to step 5. 
   664    671   **
   665    672   **   5. Otherwise, allocate and return a new page buffer.
   666    673   */
   667    674   static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
   668    675     unsigned int nPinned;
   669    676     PCache1 *pCache = (PCache1 *)p;
   670         -  PGroup *pGroup = pCache->pGroup;
          677  +  PGroup *pGroup;
   671    678     PgHdr1 *pPage = 0;
   672    679   
   673    680     assert( pCache->bPurgeable || createFlag!=1 );
   674         -  pcache1EnterMutex(pGroup);
   675         -  if( createFlag==1 ) sqlite3BeginBenignMalloc();
          681  +  assert( pCache->bPurgeable || pCache->nMin==0 );
          682  +  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
          683  +  assert( pCache->nMin==0 || pCache->bPurgeable );
          684  +  pcache1EnterMutex(pGroup = pCache->pGroup);
   676    685   
   677    686     /* Step 1: Search the hash table for an existing entry. */
   678    687     if( pCache->nHash>0 ){
   679    688       unsigned int h = iKey % pCache->nHash;
   680    689       for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
   681    690     }
   682    691   
   683    692     /* Step 2: Abort if no existing page is found and createFlag is 0 */
   684    693     if( pPage || createFlag==0 ){
   685    694       pcache1PinPage(pPage);
   686    695       goto fetch_out;
   687    696     }
          697  +
          698  +  /* The pGroup local variable will normally be initialized by the
          699  +  ** pcache1EnterMutex() macro above.  But if SQLITE_MUTEX_OMIT is defined,
          700  +  ** then pcache1EnterMutex() is a no-op, so we have to initialize the
          701  +  ** local variable here.  Delaying the initialization of pGroup is an
          702  +  ** optimization:  The common case is to exit the module before reaching
          703  +  ** this point.
          704  +  */
          705  +#ifdef SQLITE_MUTEX_OMIT
          706  +  pGroup = pCache->pGroup;
          707  +#endif
          708  +
   688    709   
   689    710     /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
   690    711     nPinned = pCache->nPage - pCache->nRecyclable;
          712  +  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
          713  +  assert( pCache->mxPinned == pCache->nMax*9/10 );
   691    714     if( createFlag==1 && (
   692         -        nPinned>=(pGroup->nMaxPage+pCache->nMin-pGroup->nMinPage)
   693         -     || nPinned>=(pCache->nMax * 9 / 10)
          715  +        nPinned>=pGroup->mxPinned
          716  +     || nPinned>=pCache->mxPinned
   694    717        || pcache1UnderMemoryPressure(pCache)
   695    718     )){
   696    719       goto fetch_out;
   697    720     }
   698    721   
   699    722     if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
   700    723       goto fetch_out;
................................................................................
   702    725   
   703    726     /* Step 4. Try to recycle a page. */
   704    727     if( pCache->bPurgeable && pGroup->pLruTail && (
   705    728            (pCache->nPage+1>=pCache->nMax)
   706    729         || pGroup->nCurrentPage>=pGroup->nMaxPage
   707    730         || pcache1UnderMemoryPressure(pCache)
   708    731     )){
          732  +    PCache1 *pOtherCache;
   709    733       pPage = pGroup->pLruTail;
   710    734       pcache1RemoveFromHash(pPage);
   711    735       pcache1PinPage(pPage);
   712         -    if( pPage->pCache->szPage!=pCache->szPage ){
          736  +    if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){
   713    737         pcache1FreePage(pPage);
   714    738         pPage = 0;
   715    739       }else{
   716    740         pGroup->nCurrentPage -= 
   717         -               (pPage->pCache->bPurgeable - pCache->bPurgeable);
          741  +               (pOtherCache->bPurgeable - pCache->bPurgeable);
   718    742       }
   719    743     }
   720    744   
   721    745     /* Step 5. If a usable page buffer has still not been found, 
   722    746     ** attempt to allocate a new one. 
   723    747     */
   724    748     if( !pPage ){
          749  +    if( createFlag==1 ) sqlite3BeginBenignMalloc();
   725    750       pcache1LeaveMutex(pGroup);
   726    751       pPage = pcache1AllocPage(pCache);
   727    752       pcache1EnterMutex(pGroup);
          753  +    if( createFlag==1 ) sqlite3EndBenignMalloc();
   728    754     }
   729    755   
   730    756     if( pPage ){
   731    757       unsigned int h = iKey % pCache->nHash;
   732    758       pCache->nPage++;
   733    759       pPage->iKey = iKey;
   734    760       pPage->pNext = pCache->apHash[h];
................................................................................
   739    765       pCache->apHash[h] = pPage;
   740    766     }
   741    767   
   742    768   fetch_out:
   743    769     if( pPage && iKey>pCache->iMaxKey ){
   744    770       pCache->iMaxKey = iKey;
   745    771     }
   746         -  if( createFlag==1 ) sqlite3EndBenignMalloc();
   747    772     pcache1LeaveMutex(pGroup);
   748    773     return (pPage ? PGHDR1_TO_PAGE(pPage) : 0);
   749    774   }
   750    775   
   751    776   
   752    777   /*
   753    778   ** Implementation of the sqlite3_pcache.xUnpin method.
................................................................................
   849    874     PCache1 *pCache = (PCache1 *)p;
   850    875     PGroup *pGroup = pCache->pGroup;
   851    876     assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
   852    877     pcache1EnterMutex(pGroup);
   853    878     pcache1TruncateUnsafe(pCache, 0);
   854    879     pGroup->nMaxPage -= pCache->nMax;
   855    880     pGroup->nMinPage -= pCache->nMin;
          881  +  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
   856    882     pcache1EnforceMaxPage(pGroup);
   857    883     pcache1LeaveMutex(pGroup);
   858    884     sqlite3_free(pCache->apHash);
   859    885     sqlite3_free(pCache);
   860    886   }
   861    887   
   862    888   /*