Changeset 2541 in CLRX


Ignore:
Timestamp:
Nov 6, 2016, 7:45:15 PM (4 years ago)
Author:
matszpk
Message:

CLRadeonExtender: Update ElfBinaries?.

Location:
CLRadeonExtender/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/CLRX/amdbin/ElfBinaries.h

    r2538 r2541  
    706706    std::vector<ElfSymbolTemplate<Types> > symbols;
    707707    std::vector<ElfSymbolTemplate<Types> > dynSymbols;
     708    uint32_t bucketsNum;
     709    std::unique_ptr<uint32_t> hashCodes;
    708710   
    709711    void computeSize();
  • CLRadeonExtender/trunk/amdbin/ElfBinaries.cpp

    r2540 r2541  
    351351
    352352template<typename Types>
     353static std::unique_ptr<uint32_t[]> calculateHashValuesForSymbols(bool addNullSymbol,
     354            const std::vector<ElfSymbolTemplate<Types> >& symbols)
     355{
     356    const size_t symsNum = symbols.size() + addNullSymbol;
     357    std::unique_ptr<uint32_t[]> hashCodes(new uint32_t[symsNum]);
     358    if (addNullSymbol)
     359        hashCodes[0] = 0;
     360    for (size_t i = 0; i < symbols.size(); i++)
     361    {
     362        uint32_t h = 0, g;
     363        const cxbyte* name = reinterpret_cast<const cxbyte*>(symbols[i].name);
     364        while(*name!=0)
     365        {
     366            h = (h<<4) + *name++;
     367            g = h & 0xf0000000U;
     368            if (g) h ^= g>>24;
     369            h &= ~g;
     370        }
     371        hashCodes[i+addNullSymbol] = h;
     372    }
     373    return hashCodes;
     374}
     375
     376/// return bucket number
     377static uint32_t optimizeHashBucketsNum(uint32_t hashNum, bool skipFirst,
     378                           const uint32_t* hashCodes)
     379{
     380    uint32_t bestBucketNum = 0;
     381    uint64_t bestValue = UINT64_MAX;
     382    uint32_t firstStep = std::max(uint32_t(hashNum>>2), 1U);
     383    uint64_t maxSteps = (uint64_t(hashNum)<<1) - (firstStep) + 1;
     384    const uint32_t steps = (maxSteps<=1000U) ? hashNum : hashNum<<((32-CLZ32(hashNum))>>1);
     385   
     386    std::unique_ptr<uint32_t[]> chainLengths(new uint32_t[(hashNum<<2)+1]);
     387    const uint32_t stepSize = maxSteps / steps;
     388    for (uint32_t buckets = firstStep; buckets <= (hashNum<<1); buckets += stepSize)
     389    {   //
     390        std::fill(chainLengths.get(), chainLengths.get() + buckets, 0U);
     391        // calculate chain lengths
     392        for (size_t i = skipFirst; i < hashNum; i++)
     393            chainLengths[hashCodes[i] % buckets]++;
     394        /// value, smaller is better
     395        uint64_t value = uint64_t(buckets);
     396        for (uint32_t i = 0; i < buckets; i++)
     397            value += chainLengths[i]*chainLengths[i];
     398        if (value < bestValue)
     399        {
     400            bestBucketNum = buckets;
     401            bestValue = value;
     402        }
     403    }
     404    return bestBucketNum;
     405}
     406
     407template<typename Types>
    353408ElfBinaryGenTemplate<Types>::ElfBinaryGenTemplate()
    354409        : sizeComputed(false), addNullSym(true), addNullDynSym(true), addNullSection(true),
    355410          addrStartRegion(0), shStrTab(0), strTab(0), dynStr(0), shdrTabRegion(0),
    356           phdrTabRegion(0)
     411          phdrTabRegion(0), bucketsNum(0)
    357412{ }
    358413
     
    364419          addNullSection(_addNullSection),  addrStartRegion(addrCountingFromRegion),
    365420          shStrTab(0), strTab(0), dynStr(0), shdrTabRegion(0), phdrTabRegion(0),
    366           header(_header)
     421          header(_header), bucketsNum(0)
    367422{ }
    368423
     
    392447        if (region.type == ElfRegionType::SECTION)
    393448            sectionsNum++;
     449   
    394450    sectionRegions.reset(new cxuint[sectionsNum+1]);
    395451    sectionRegions[0] = UINT_MAX;
     
    454510                    size += uint64_t(dynSymbols.size()+addNullDynSym)*
    455511                                sizeof(typename Types::Sym);
     512                else if (region.section.type == SHT_HASH)
     513                {
     514                    sectionRegions.
     515                    calculateHashValuesForSymbols<>()
     516                }
    456517                else if (region.section.type == SHT_STRTAB)
    457518                {
     
    507568    computeSize();
    508569    return size;
    509 }
    510 
    511 template<typename Types>
    512 static std::unique_ptr<uint32_t[]> calculateHashValuesForSymbols(bool addNullSymbol,
    513             const std::vector<ElfSymbolTemplate<Types> >& symbols)
    514 {
    515     const size_t symsNum = symbols.size() + addNullSymbol;
    516     std::unique_ptr<uint32_t[]> hashCodes(new uint32_t[symsNum]);
    517     if (addNullSymbol)
    518         hashCodes[0] = 0;
    519     for (size_t i = 0; i < symbols.size(); i++)
    520     {
    521         uint32_t h = 0, g;
    522         const cxbyte* name = reinterpret_cast<const cxbyte*>(symbols[i].name);
    523         while(*name!=0)
    524         {
    525             h = (h<<4) + *name++;
    526             g = h & 0xf0000000U;
    527             if (g) h ^= g>>24;
    528             h &= ~g;
    529         }
    530         hashCodes[i+addNullSymbol] = h;
    531     }
    532     return hashCodes;
    533 }
    534 
    535 /// return bucket number
    536 static uint32_t optimizeHashBucketsNum(uint32_t hashNum, bool skipFirst,
    537                            const uint32_t* hashCodes)
    538 {
    539     uint32_t bestBucketNum = 0;
    540     uint64_t bestValue = UINT64_MAX;
    541     uint32_t firstStep = std::max(uint32_t(hashNum>>2), 1U);
    542     uint64_t maxSteps = (uint64_t(hashNum)<<1) - (firstStep) + 1;
    543     const uint32_t steps = (maxSteps<=1000U) ? hashNum : hashNum<<((32-CLZ32(hashNum))>>1);
    544    
    545     std::unique_ptr<uint32_t[]> chainLengths(new uint32_t[(hashNum<<2)+1]);
    546     const uint32_t stepSize = maxSteps / steps;
    547     for (uint32_t buckets = firstStep; buckets <= (hashNum<<1); buckets += stepSize)
    548     {   //
    549         std::fill(chainLengths.get(), chainLengths.get() + buckets, 0U);
    550         // calculate chain lengths
    551         for (size_t i = skipFirst; i < hashNum; i++)
    552             chainLengths[hashCodes[i] % buckets]++;
    553         /// value, smaller is better
    554         uint64_t value = uint64_t(buckets);
    555         for (uint32_t i = 0; i < buckets; i++)
    556             value += chainLengths[i]*chainLengths[i];
    557         if (value < bestValue)
    558         {
    559             bestBucketNum = buckets;
    560             bestValue = value;
    561         }
    562     }
    563     return bestBucketNum;
    564570}
    565571
Note: See TracChangeset for help on using the changeset viewer.