github.com/eth-easl/loader@v0.0.0-20230908084258-8a37e1d94279/pkg/trace/profiler.go (about) 1 /* 2 * MIT License 3 * 4 * Copyright (c) 2023 EASL and the vHive community 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 package trace 26 27 import ( 28 "github.com/eth-easl/loader/pkg/common" 29 log "github.com/sirupsen/logrus" 30 "math" 31 ) 32 33 func DoStaticTraceProfiling(functions []*common.Function) { 34 for i := 0; i < len(functions); i++ { 35 f := functions[i] 36 37 f.InitialScale = int(math.Ceil(profileConcurrency(functions[i]))) 38 log.Debugf("Function %s initial scale will be %d.\n", f.Name, f.InitialScale) 39 } 40 } 41 42 func ApplyResourceLimits(functions []*common.Function) { 43 for i := 0; i < len(functions); i++ { 44 memoryPct100 := int(functions[i].MemoryStats.Percentile100) 45 cpuShare := ConvertMemoryToCpu(memoryPct100) 46 47 functions[i].CPURequestsMilli = cpuShare / common.OvercommitmentRatio 48 functions[i].MemoryRequestsMiB = memoryPct100 / common.OvercommitmentRatio 49 functions[i].CPULimitsMilli = cpuShare 50 } 51 } 52 53 // ConvertMemoryToCpu Google Cloud Function conversion table used from https://cloud.google.com/functions/pricing 54 func ConvertMemoryToCpu(memoryRequest int) int { 55 var cpuRequest float32 56 switch memoryRequest = common.MinOf(common.MaxMemQuotaMib, common.MaxOf(common.MinMemQuotaMib, memoryRequest)); { 57 case memoryRequest < 256: 58 cpuRequest = 0.083 59 case memoryRequest < 512: 60 cpuRequest = 0.167 61 case memoryRequest < 1024: 62 cpuRequest = 0.333 63 case memoryRequest < 2048: 64 cpuRequest = 0.583 65 case memoryRequest < 4096: 66 cpuRequest = 1 67 default: 68 cpuRequest = 2 69 } 70 71 return int(cpuRequest * 1000) 72 } 73 74 func profileConcurrency(function *common.Function) float64 { 75 IPM := function.InvocationStats.Invocations[0] 76 77 // Arrival rate - unit 1 s 78 rps := float64(IPM) / 60.0 79 // Processing rate = runtime_in_milli / 1000, assuming it can be process right away upon arrival. 80 processingRate := float64(function.RuntimeStats.Average) / 1000.0 81 // Expected concurrency == the inventory (total #jobs in the system) of Little's law. 82 concurrency := rps * processingRate 83 84 return concurrency 85 }