//template<typename BitPacker> public bool encodeOmega(ref BitPacker packer, uint val) { // Most of the time (94% in a few tests) val was 8 bits or less. if (val < OmegaCodeTableSize) return packer.encodeSmall(mOmegaCodeTable[val].mCode, mOmegaCodeTable[val].mLen); int len; UInt64 code = getOmegaCode(out len, val); return packer.encode(code, len); }
// false on failure //template<typename BitPackerType> public bool codeSample(BitPacker bitPacker, /*const*/ ref BRetiredProfileSample sample, /*const*/ ref BProfileSection pSection) { if (sample.mSectionID >= size(mSectionPredDataArray)) { resize(ref mSectionPredDataArray, sample.mSectionID + 1); } /*const*/ uint /*BCoderTime*/ cpuStartTime = sample.mCPUStartTime; /*const*/ uint /*BCoderTime*/ cpuEndTime = sample.mCPUEndTime; uint /*BCoderTime*/ gpuStartTime = 0; uint /*BCoderTime*/ gpuEndTime = 0; if (!pSection.cpuOnly()) { gpuStartTime = sample.mGPUStartTime; gpuEndTime = sample.mGPUEndTime; } uint /*BCoderTime*/ cpuDuration = cpuEndTime - cpuStartTime; uint /*BCoderTime*/ gpuDuration = gpuEndTime - gpuStartTime; if (-1 == mPrevLevel) { if (!mCoder.encodeOmega(ref bitPacker, sample.mSectionID)) { return(false); } // Model is empty - send uncompressed sample if (!mCoder.encodeOmega(ref bitPacker, sample.mLevel)) { return(false); } if (!mCoder.encodeOmega(ref bitPacker, sample.mUserID)) { return(false); } if (!bitPacker.encode(cpuStartTime, 32)) { return(false); } if (!bitPacker.encode(cpuEndTime, 32)) { return(false); } if (!pSection.cpuOnly()) { if (!bitPacker.encode(gpuStartTime, 32)) { return(false); } if (!bitPacker.encode(gpuEndTime, 32)) { return(false); } } } else { // Compress sample // Code the section ID delta int sectionIDDelta = (int)(sample.mSectionID - mSectionPredDataArray[mPrevSectionID].mNextSectionID); if (!mCoder.encodeOmegaSigned(ref bitPacker, sectionIDDelta)) { return(false); } // Code the level delta using 1 or 2 bits [-1, 0, or 1] /*const*/ int levelDelta = sample.mLevel - mPrevLevel; if (!mCoder.encodeOmegaSigned(ref bitPacker, levelDelta)) { return(false); } /*const*/ int userIDDelta = (int)(sample.mUserID - mPrevUserID); if (userIDDelta == 0) { // Encode single bit to represent userIDDelta == 0. if (!bitPacker.encode((uint)(0), (int)(1))) { return(false); } } else { if (!bitPacker.encode((uint)(1), (int)(1))) { return(false); } if (!mCoder.encodeOmegaSigned(ref bitPacker, userIDDelta)) { return(false); } } uint predStartCPUTime = mPrevCPUEndTime; if (sample.mLevel > mPrevLevel) { predStartCPUTime = mPrevCPUStartTime; } //BDEBUG_ASSERT(predStartCPUTime <= cpuStartTime); /*const*/ uint deltaStartCPUTime = cpuStartTime - mPrevCPUStartTime; if (!mCoder.encodeOmega(ref bitPacker, deltaStartCPUTime)) { return(false); } /*const*/ int deltaCPUDuration = (int)(cpuDuration - mSectionPredDataArray[sample.mSectionID].mPrevCPUDuration); if (!mCoder.encodeOmegaSigned(ref bitPacker, deltaCPUDuration)) { return(false); } if (!pSection.cpuOnly()) { uint predStartGPUTime = mPrevGPUEndTime; if (sample.mLevel > mPrevLevel) { predStartGPUTime = mPrevGPUStartTime; } if (!sample.hasGPUTimes()) { // this should be very rare-- only when the gpu samples time out // we don't want to try encoding a negative start gpu time delta // instead, ensure the gpu times are both equal, which means the sample is invalid gpuStartTime = predStartGPUTime; gpuEndTime = predStartGPUTime; gpuDuration = 0; } //BDEBUG_ASSERT(predStartGPUTime <= gpuStartTime); /*const*/ uint deltaStartGPUTime = gpuStartTime - mPrevGPUStartTime; if (!mCoder.encodeOmega(ref bitPacker, deltaStartGPUTime)) { return(false); } /*const*/ int deltaGPUDuration = (int)(gpuDuration - mSectionPredDataArray[sample.mSectionID].mPrevGPUDuration); if (!mCoder.encodeOmegaSigned(ref bitPacker, deltaGPUDuration)) { return(false); } } } // Update the model - only record those things we need for speed mSectionPredDataArray[sample.mSectionID].mPrevCPUDuration = cpuDuration; mSectionPredDataArray[sample.mSectionID].mPrevGPUDuration = gpuDuration; mSectionPredDataArray[mPrevSectionID].mNextSectionID = sample.mSectionID; mPrevLevel = sample.mLevel; mPrevUserID = sample.mUserID; mPrevSectionID = sample.mSectionID; mPrevCPUStartTime = cpuStartTime; mPrevCPUEndTime = cpuEndTime; mPrevGPUStartTime = gpuStartTime; mPrevGPUEndTime = gpuEndTime; return(true); }