// 該当するTTEntryを返す。 const TTEntry& TranspositionTable::GetEntry(Hash pos_hash, int depth) const { // エントリーを得る。 std::size_t index = GetTableIndex(pos_hash); if ((entry_table_[index].depth() >= depth) && (entry_table_[index].pos_hash() == pos_hash)) { return entry_table_[index]; } // 条件外なので、無効なエントリーを返す。 return null_entry_; }
// 該当するTTEntryを返す。 TTEntry* TranspositionTable::GetEntry(Hash pos_hash, int depth) { std::unique_lock<std::mutex> lock(mutex_); // ロック。 // エントリーを得る。 TTEntry* entry_ptr = nullptr; std::size_t index = GetTableIndex(pos_hash); if ((entry_table_[index].depth() >= depth) && (entry_table_[index].pos_hash() == pos_hash)) { entry_ptr = &(entry_table_[index]); } return entry_ptr; }
ezResult ezImageConversionBase::Convert(const ezImage& source, ezImage& target, ezImageFormat::Enum targetFormat) { ezImageFormat::Enum sourceFormat = source.GetImageFormat(); // Trivial copy if (sourceFormat == targetFormat) { target = source; return EZ_SUCCESS; } if (!s_bConversionTableValid) { RebuildConversionTable(); } ezUInt32 uiCurrentTableIndex = GetTableIndex(sourceFormat, targetFormat); // No conversion known if (s_conversionTable[uiCurrentTableIndex] == nullptr) { return EZ_FAILURE; } const ezImageConversionBase* pConversion = s_conversionTable[uiCurrentTableIndex]; const SubConversion& subConversion = pConversion->m_subConversions[s_subConversionTable[uiCurrentTableIndex]]; if (subConversion.m_targetFormat == targetFormat) { if (&source == &target && !subConversion.m_flags.IsSet(ezImageConversionFlags::InPlace)) { ezImage copy = source; return pConversion->DoConvert(copy, target, subConversion.m_targetFormat); } else { return pConversion->DoConvert(source, target, subConversion.m_targetFormat); } } else { ezImage intermediate; if (pConversion->DoConvert(source, intermediate, subConversion.m_targetFormat) == EZ_FAILURE) { return EZ_FAILURE; } return Convert(intermediate, target, targetFormat); } }
// テーブルに追加する。 void TranspositionTable::Add(Hash pos_hash, int depth, int score, ScoreType score_type, Move best_move, int ply_mate) { std::unique_lock<std::mutex> lock(mutex_); // ロック。 // テーブルのインデックスを得る。 std::size_t index = GetTableIndex(pos_hash); // 空いているエントリーへの登録なら使用済みエントリー数をカウント。 if (entry_table_[index].depth() <= -MAX_VALUE) { num_used_entries_++; } // テーブルが若い時にに登録されているものなら上書き。 // depthがすでに登録されているエントリー以上なら登録。 if ((entry_table_[index].table_age() < age_) || (depth >= entry_table_[index].depth())) { entry_table_[index] = TTEntry(pos_hash, depth, score, score_type, best_move, ply_mate, age_); } }
ezImageFormat::Enum ezImageConversionBase::FindClosestCompatibleFormat(ezImageFormat::Enum format, const ezImageFormat::Enum* pCompatibleFormats, ezUInt32 uiNumCompatible) { if (!s_bConversionTableValid) { RebuildConversionTable(); } float fBestCost = ezMath::BasicType<float>::GetInfinity(); ezImageFormat::Enum bestFormat = ezImageFormat::UNKNOWN; for (ezUInt32 uiTargetIndex = 0; uiTargetIndex < uiNumCompatible; uiTargetIndex++) { float fCost = s_costTable[GetTableIndex(format, pCompatibleFormats[uiTargetIndex])]; if (fCost < fBestCost) { fBestCost = fCost; bestFormat = pCompatibleFormats[uiTargetIndex]; } } return bestFormat; }
/** Loads a 2DA Table, returns -1 on error or the Table Index on success */ int GameData::LoadTable(const ieResRef ResRef, bool silent) { int ind = GetTableIndex( ResRef ); if (ind != -1) { tables[ind].refcount++; return ind; } //print("(%s) Table not found... Loading from file", ResRef); DataStream* str = GetResource( ResRef, IE_2DA_CLASS_ID, silent ); if (!str) { return -1; } PluginHolder<TableMgr> tm(IE_2DA_CLASS_ID); if (!tm) { delete str; return -1; } if (!tm->Open(str)) { return -1; } Table t; t.refcount = 1; strncpy( t.ResRef, ResRef, 8 ); t.tm = tm; ind = -1; for (size_t i = 0; i < tables.size(); i++) { if (tables[i].refcount == 0) { ind = ( int ) i; break; } } if (ind != -1) { tables[ind] = t; return ind; } tables.push_back( t ); return ( int ) tables.size() - 1; }
void ezImageConversionBase::RebuildConversionTable() { s_conversionTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS); s_subConversionTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS); s_costTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS); for (ezUInt32 tableIdx = 0; tableIdx < s_conversionTable.GetCount(); tableIdx++) { s_conversionTable[tableIdx] = nullptr; s_costTable[tableIdx] = ezMath::BasicType<float>::GetInfinity(); } // Prime conversion table with known conversions for (ezImageConversionBase* pConversion = ezImageConversionBase::GetFirstInstance(); pConversion; pConversion = pConversion->GetNextInstance()) { for (ezUInt32 uiSubConversion = 0; uiSubConversion < pConversion->m_subConversions.GetCount(); uiSubConversion++) { const SubConversion& subConversion = pConversion->m_subConversions[uiSubConversion]; if (subConversion.m_flags.IsSet(ezImageConversionFlags::InPlace)) { EZ_ASSERT_DEBUG(ezImageFormat::GetBitsPerPixel(subConversion.m_sourceFormat) == ezImageFormat::GetBitsPerPixel(subConversion.m_targetFormat), "In-place conversions are only allowed between formats of the same number of bits per pixel"); EZ_ASSERT_DEBUG(ezImageFormat::GetType(subConversion.m_sourceFormat) == ezImageFormat::GetType(subConversion.m_targetFormat), "In-place conversions are only allowed between formats of the same type"); } ezUInt32 uiTableIndex = GetTableIndex(subConversion.m_sourceFormat, subConversion.m_targetFormat); // Use the cheapest known conversion for each combination in case there are multiple ones if (s_costTable[uiTableIndex] > GetConversionCost(subConversion.m_flags)) { s_conversionTable[uiTableIndex] = pConversion; s_subConversionTable[uiTableIndex] = uiSubConversion; s_costTable[uiTableIndex] = GetConversionCost(subConversion.m_flags); } } } for (ezUInt32 i = 0; i < ezImageFormat::NUM_FORMATS; i++) { // Add copy-conversion (from and to same format) s_costTable[GetTableIndex(i, i)] = GetConversionCost(ezImageConversionFlags::InPlace); } // Straight from http://en.wikipedia.org/wiki/Floyd-Warshall_algorithm for (ezUInt32 k = 0; k < ezImageFormat::NUM_FORMATS; k++) { for (ezUInt32 i = 0; i < ezImageFormat::NUM_FORMATS; i++) { ezUInt32 uiTableIndexIK = GetTableIndex(i, k); for (ezUInt32 j = 0; j < ezImageFormat::NUM_FORMATS; j++) { ezUInt32 uiTableIndexIJ = GetTableIndex(i, j); ezUInt32 uiTableIndexKJ = GetTableIndex(k, j); if (s_costTable[uiTableIndexIK] + s_costTable[uiTableIndexKJ] < s_costTable[uiTableIndexIJ]) { s_costTable[uiTableIndexIJ] = s_costTable[uiTableIndexIK] + s_costTable[uiTableIndexKJ]; const ezImageConversionBase* pConversion = s_conversionTable[uiTableIndexIK]; // To convert from format I to format J, first convert from I to K s_conversionTable[uiTableIndexIJ] = pConversion; s_subConversionTable[uiTableIndexIJ] = s_subConversionTable[uiTableIndexIK]; } } } } s_bConversionTableValid = true; }
// -------------------------------------------------------------------------------------- // // Stores hot data reported by IBC in profile data (code:CorProfileData) to a stream. // Aligns output stream to 4-bytes. // __checkReturn HRESULT HotHeapWriter::SaveToStream( IStream *pStream, CorProfileData *pProfileData, UINT32 *pnSavedSize) const { _ASSERTE(pStream != NULL); _ASSERTE(pProfileData != NULL); _ASSERTE(pnSavedSize != NULL); #ifdef FEATURE_PREJIT HRESULT hr = S_OK; UINT32 nOffset = 0; UINT32 nValueHeapStart_PositiveOffset; UINT32 nValueOffsetTableStart_PositiveOffset; UINT32 nIndexTableStart_PositiveOffset; // data // // number of hot tokens UINT32 nHotItemsCount = pProfileData->GetHotTokens( GetTableIndex(), 1 << ProfilingFlags_MetaData, 1 << ProfilingFlags_MetaData, NULL, 0); CONSISTENCY_CHECK(nHotItemsCount != 0); NewArrayHolder<UINT32> hotItemArr = new (nothrow) UINT32[nHotItemsCount]; IfNullRet(hotItemArr); // get hot tokens static_assert_no_msg(sizeof(UINT32) == sizeof(mdToken)); pProfileData->GetHotTokens( GetTableIndex(), 1 << ProfilingFlags_MetaData, 1 << ProfilingFlags_MetaData, reinterpret_cast<mdToken *>(&hotItemArr[0]), nHotItemsCount); // convert tokens to rids for (UINT32 i = 0; i < nHotItemsCount; i++) { hotItemArr[i] = RidFromToken(hotItemArr[i]); } NewArrayHolder<RidOffsetPair> offsetMapping = new (nothrow) RidOffsetPair[nHotItemsCount]; IfNullRet(offsetMapping); // write data nValueHeapStart_PositiveOffset = nOffset; // note that we write hot items in the order they appear in pProfileData->GetHotTokens // this is so that we preserve the ordering optimizations done by IbcMerge for (UINT32 i = 0; i < nHotItemsCount; i++) { DataBlob data; IfFailRet(GetData( hotItemArr[i], &data)); // keep track of the offset at which each hot item is written offsetMapping[i].rid = hotItemArr[i]; offsetMapping[i].offset = nOffset; IfFailRet(StreamUtil::WriteToStream( pStream, data.GetDataPointer(), data.GetSize(), &nOffset)); } IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset)); // sort by rid so that a hot rid can be looked up by binary search qsort(offsetMapping, nHotItemsCount, sizeof(RidOffsetPair), RidOffsetPair::Compare); // initialize table of offsets to data NewArrayHolder<UINT32> dataIndices = new (nothrow) UINT32[nHotItemsCount]; IfNullRet(dataIndices); // fill in the hotItemArr (now sorted by rid) and dataIndices array with each offset for (UINT32 i = 0; i < nHotItemsCount; i++) { hotItemArr[i] = offsetMapping[i].rid; dataIndices[i] = offsetMapping[i].offset; } // table of offsets to data // nValueOffsetTableStart_PositiveOffset = nOffset; IfFailRet(StreamUtil::WriteToStream(pStream, &dataIndices[0], sizeof(UINT32) * nHotItemsCount, &nOffset)); // rid table (sorted) // nIndexTableStart_PositiveOffset = nOffset; IfFailRet(StreamUtil::WriteToStream(pStream, &hotItemArr[0], nHotItemsCount * sizeof(UINT32), &nOffset)); IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset)); { // hot pool header struct HotHeapHeader header; // fix offsets header.m_nIndexTableStart_NegativeOffset = nOffset - nIndexTableStart_PositiveOffset; header.m_nValueOffsetTableStart_NegativeOffset = nOffset - nValueOffsetTableStart_PositiveOffset; header.m_nValueHeapStart_NegativeOffset = nOffset - nValueHeapStart_PositiveOffset; // write header IfFailRet(StreamUtil::WriteToStream(pStream, &header, sizeof(header), &nOffset)); } *pnSavedSize = nOffset; #endif //FEATURE_PREJIT return S_OK; } // HotHeapWriter::PersistHotToStream