func()

in cpc/compression_characterization.go [132:314]


func (cc *CompressionCharacterization) doTrialsAtLgKAtN(lgK int, n int64, totalTrials int) error {
	k := 1 << lgK
	minNK := k
	if int64(k) > n {
		minNK = int(n)
	}
	nOverK := float64(n) / float64(k)
	lgTotTrials := bits.TrailingZeros32(uint32(totalTrials))
	// We'll define waves = 2^(lgWaves). Each wave has trialsPerWave = 2^(lgTotTrials - lgWaves).
	lgWaves := lgTotTrials - 10
	if lgWaves < 0 {
		lgWaves = 0
	}
	trialsPerWave := 1 << (lgTotTrials - lgWaves)
	wavesCount := 1 << lgWaves

	streamSketches := make([]*CpcSketch, trialsPerWave)
	compressedStates1 := make([]*CpcCompressedState, trialsPerWave)
	memoryArr := make([][]byte, trialsPerWave)
	compressedStates2 := make([]*CpcCompressedState, trialsPerWave)
	unCompressedSketches := make([]*CpcSketch, trialsPerWave)

	var totalC, totalW int64
	var sumCtorNS, sumUpdNS, sumComNS, sumSerNS, sumDesNS, sumUncNS, sumEquNS int64

	startTime := time.Now()

	// wave loop
	for w := 0; w < wavesCount; w++ {
		// Construct sketches
		nanoStart := time.Now().UnixNano()
		for t := 0; t < trialsPerWave; t++ {
			sketch, err := NewCpcSketch(lgK, internal.DEFAULT_UPDATE_SEED)
			if err != nil {
				return err
			}
			streamSketches[t] = sketch
		}
		nanoEnd := time.Now().UnixNano()
		sumCtorNS += nanoEnd - nanoStart
		nanoStart = nanoEnd

		// Update each sketch
		for t := 0; t < trialsPerWave; t++ {
			sketch := streamSketches[t]
			for i := int64(0); i < n; i++ {
				cc.vIn += common.InverseGoldenU64
				_ = sketch.UpdateUint64(cc.vIn)
			}
		}
		nanoEnd = time.Now().UnixNano()
		sumUpdNS += nanoEnd - nanoStart
		nanoStart = nanoEnd

		// Compress each sketch
		for t := 0; t < trialsPerWave; t++ {
			sketch := streamSketches[t]
			state, err := NewCpcCompressedStateFromSketch(sketch)
			if err != nil {
				panic(fmt.Sprintf("Compression error: %v", err))
			}
			compressedStates1[t] = state
			totalC += int64(sketch.numCoupons)
			// approximate measure of total words in CSV + CW
			totalW += int64(state.CsvLengthInts + state.CwLengthInts)
		}
		nanoEnd = time.Now().UnixNano()
		sumComNS += nanoEnd - nanoStart
		nanoStart = nanoEnd

		// Convert each CompressedState to a byte slice
		for t := 0; t < trialsPerWave; t++ {
			state := compressedStates1[t]
			mem, err := state.exportToMemory()
			if err != nil {
				panic(fmt.Sprintf("exportToMemory error: %v", err))
			}
			memoryArr[t] = mem
		}
		nanoEnd = time.Now().UnixNano()
		sumSerNS += nanoEnd - nanoStart
		nanoStart = nanoEnd

		// Import from memory to new CompressedState
		for t := 0; t < trialsPerWave; t++ {
			mem := memoryArr[t]
			state, err := importFromMemory(mem)
			if err != nil {
				panic(fmt.Sprintf("importFromMemory error: %v", err))
			}
			compressedStates2[t] = state
		}
		nanoEnd = time.Now().UnixNano()
		sumDesNS += nanoEnd - nanoStart
		nanoStart = nanoEnd

		// Uncompress into a new CpcSketch
		for t := 0; t < trialsPerWave; t++ {
			state := compressedStates2[t]
			uncSk, err := uncompressSketch(state, internal.DEFAULT_UPDATE_SEED)
			if err != nil {
				return err
			}
			unCompressedSketches[t] = uncSk
		}
		nanoEnd = time.Now().UnixNano()
		sumUncNS += nanoEnd - nanoStart
		nanoStart = nanoEnd

		// Equality check
		for t := 0; t < trialsPerWave; t++ {
			s1 := streamSketches[t]
			s2 := unCompressedSketches[t]
			if !specialEquals(s1, s2, false, false) {
				return fmt.Errorf("uncompressed sketch not equal to original")
			}
		}
		nanoEnd = time.Now().UnixNano()
		sumEquNS += nanoEnd - nanoStart
		nanoStart = nanoEnd
	}

	totalSeconds := time.Since(startTime).Seconds()
	avgC := float64(totalC) / float64(totalTrials)
	avgCoK := avgC / float64(k)
	avgWords := float64(totalW) / float64(totalTrials)
	avgBytes := 4.0 * avgWords // 4 bytes per int

	// compute average times
	// Each sum is total for all waves, so we divide by totalTrials
	avgCtor := float64(sumCtorNS) / float64(totalTrials)
	avgUpd := float64(sumUpdNS) / float64(totalTrials)
	avgCom := float64(sumComNS) / float64(totalTrials)
	avgSer := float64(sumSerNS) / float64(totalTrials)
	avgDes := float64(sumDesNS) / float64(totalTrials)
	avgUnc := float64(sumUncNS) / float64(totalTrials)
	avgEqu := float64(sumEquNS) / float64(totalTrials)

	avgUpdPerN := avgUpd / float64(n)
	avgComPer2C := avgCom / (2.0 * avgC)
	avgComPerK := avgCom / float64(k)
	avgSerPerW := avgSer / avgWords
	avgDesPerW := avgDes / avgWords
	avgUncPer2C := avgUnc / (2.0 * avgC)
	avgUncPerK := avgUnc / float64(k)
	avgEquPerMinNK := avgEqu / float64(minNK)

	// final flavor/offset from last wave
	lastSketch := unCompressedSketches[len(unCompressedSketches)-1]
	finFlavor := lastSketch.getFlavor()
	finOff := lastSketch.windowOffset
	flavorOff := fmt.Sprintf("%s%2d", finFlavor.String(), finOff)

	// Print final line
	cc.printf(
		cc.dfmt,
		lgK,
		totalTrials,
		n,
		minNK,
		avgCoK,
		flavorOff,
		nOverK,
		avgBytes,
		avgCtor,
		avgUpd,
		avgCom,
		avgSer,
		avgDes,
		avgUnc,
		avgEqu,
		avgUpdPerN,
		avgComPer2C,
		avgComPerK,
		avgSerPerW,
		avgDesPerW,
		avgUncPer2C,
		avgUncPerK,
		avgEquPerMinNK,
		totalSeconds,
	)
	return nil
}