gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/host/contractmanager/contractmanager_bench_test.go (about)

     1  package contractmanager
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  
     7  	"gitlab.com/NebulousLabs/fastrand"
     8  )
     9  
    10  // BenchmarkSectorLocations explores the cost of creating the sectorLocations
    11  // map when there are 24 million elements to load. 24 million elements would
    12  // cover 96 TiB of data storage.
    13  //
    14  // On my t540p it takes about 10 seconds to create a map with 24 million
    15  // elements in it, via random insertions. The map appears to consume
    16  // approximately 1.2 GiB of RAM. In terms of performance, lock contention within
    17  // the contract manager is by far the bottleneck when compared to the cost of
    18  // interacting with massive maps.
    19  func BenchmarkSectorLocations(b *testing.B) {
    20  	// Create a bunch of data to insert into the map - metadata equivalent to
    21  	// storing 96 TiB in the contract manager.
    22  	ids := make([][12]byte, 24e6)
    23  	sectorLocations := make([]sectorLocation, 24e6)
    24  	// Fill out the arrays in 8 threads.
    25  	var wg sync.WaitGroup
    26  	for i := 0; i < 8; i++ {
    27  		wg.Add(1)
    28  		go func(i int) {
    29  			defer wg.Done()
    30  
    31  			for j := i * 3e6; j < i*3e6+3e6; j++ {
    32  				fastrand.Read(ids[j][:])
    33  				sectorLocations[j] = sectorLocation{
    34  					index:         uint32(fastrand.Intn(1 << 32)),
    35  					storageFolder: uint16(fastrand.Intn(1 << 16)),
    36  					count:         uint16(fastrand.Intn(1 << 16)),
    37  				}
    38  			}
    39  		}(i)
    40  	}
    41  	wg.Wait()
    42  
    43  	// Reset the timer and then benchmark the cost of doing 24 million
    44  	// insertions into a map - equivalent to initializng the map for a host
    45  	// storing 96 TiB of data.
    46  	b.ResetTimer()
    47  	for i := 0; i < b.N; i++ {
    48  		m := make(map[sectorID]sectorLocation)
    49  		for i := 0; i < 24e6; i++ {
    50  			m[ids[i]] = sectorLocations[i]
    51  		}
    52  	}
    53  }
    54  
    55  // BenchmarkStorageFolders explores the cost of maintaining and updating a
    56  // massive usage array. The storageFolder object is small and fast with the
    57  // exception of the usage array, which is why benchmarking is focused on the
    58  // usage array.
    59  //
    60  // The usage array for 96 TiB of storage consumes less than 10 MB of RAM, far
    61  // dwarfed by the size of the corresponding sectorLocations map that is used to
    62  // support it.
    63  func BenchmarkStorageFolders(b *testing.B) {
    64  	// Create a massive usage array, matching a 96 TiB storage folder on disk.
    65  	// The array is a bit-array, so 24e6 sectors (96 TiB) is represented by
    66  	// 375e3 usage elements.
    67  	usage := make([]uint64, 375e3)
    68  
    69  	// Fill the folder to ~99.99% capacity, which will degrade performance.
    70  	for i := 0; i < 23999e3; i++ {
    71  		randFreeSector(usage)
    72  	}
    73  
    74  	// Perform insertions and get a benchmark.
    75  	b.ResetTimer()
    76  	for i := 0; i < b.N; i++ {
    77  		randFreeSector(usage)
    78  	}
    79  }