commit 033fc6aaa8f27f131c0dd8e540594c1aeba84486 Author: tobias Date: Sat Feb 8 11:11:03 2025 +0100 first commit diff --git a/gobench.go b/gobench.go new file mode 100644 index 0000000..ebcddd0 --- /dev/null +++ b/gobench.go @@ -0,0 +1,73 @@ +package main + +import ( + "crypto/sha256" + "fmt" + "runtime" + "sync" + "time" +) + +// hashTask calculates SHA-256 hashes for the given number of iterations. +func hashTask(iterations int) { + data := []byte("benchmarking-sha256") + for i := 0; i < iterations; i++ { + _ = sha256.Sum256(data) + } +} + +// benchmarkSingleCore benchmarks single-core performance. +func benchmarkSingleCore(iterations int) float64 { + start := time.Now() + hashTask(iterations) + duration := time.Since(start).Seconds() + return float64(iterations) / duration // Return raw score +} + +// benchmarkMultiCore benchmarks multi-core performance. +func benchmarkMultiCore(iterations int, cores int) float64 { + var wg sync.WaitGroup + wg.Add(cores) + start := time.Now() + + for i := 0; i < cores; i++ { + go func() { + hashTask(iterations / cores) + wg.Done() + }() + } + + wg.Wait() + duration := time.Since(start).Seconds() + return float64(iterations) / duration // Return raw score +} + +// humanReadable formats numbers into human-readable units. +func humanReadable(score float64) string { + units := []string{"", "K", "M", "G", "T", "P", "E", "Z"} + i := 0 + for score >= 1000 && i < len(units)-1 { + score /= 1000 + i++ + } + return fmt.Sprintf("%.2f %s", score, units[i]) +} + +func main() { + iterations := 1_000_000 // Adjust this number for longer or shorter tests + + fmt.Println("Starting CPU benchmark...") + + // Single-core benchmark + fmt.Println("Benchmarking single-core performance...") + singleCoreScore := benchmarkSingleCore(iterations) + fmt.Printf("Single-core score: %s hashes/sec\n", humanReadable(singleCoreScore)) + + // Multi-core benchmark + cores := runtime.NumCPU() + fmt.Println("Benchmarking multi-core performance...") + multiCoreScore := benchmarkMultiCore(iterations, cores) + fmt.Printf("Multi-core score: %s hashes/sec\n", humanReadable(multiCoreScore)) + + fmt.Println("CPU Benchmark completed.") +} diff --git a/gobench2.go b/gobench2.go new file mode 100644 index 0000000..d82aa21 --- /dev/null +++ b/gobench2.go @@ -0,0 +1,234 @@ +package main + +import ( + "bytes" + "compress/gzip" + "crypto/sha256" + "encoding/base64" + "encoding/binary" + "fmt" + "math" + "math/rand" + "os" + "runtime" + "sort" + "sync" + "time" +) + +// Workload functions + +func performIntegerArithmetic(iterations int) { + result := 0 + for i := 0; i < iterations; i++ { + result += i * i + } + _ = result +} + +func performFloatingPointArithmetic(iterations int) { + result := 0.0 + for i := 0; i < iterations; i++ { + result += math.Sin(float64(i)) * math.Cos(float64(i)) + } + _ = result +} + +func performSorting(iterations int) { + for i := 0; i < iterations; i++ { + data := make([]int, 100) + for j := range data { + data[j] = rand.Intn(1000) + } + sort.Ints(data) + } +} + +func performHashing(iterations int) { + data := []byte("initial-hash-data") + for i := 0; i < iterations; i++ { + hash := sha256.Sum256(data) + data = hash[:] + } +} + +// Compression throughput: Fixed duration +func performCompressionThroughput(duration time.Duration) float64 { + data := bytes.Repeat([]byte("compress-this-data"), 10) // Data to compress (200 bytes) + var buf bytes.Buffer + totalBytes := 0 + start := time.Now() + + for { + buf.Reset() + writer := gzip.NewWriter(&buf) + _, err := writer.Write(data) + if err != nil { + fmt.Println("Error during compression:", err) + return 0 + } + _ = writer.Close() + totalBytes += len(data) + + if time.Since(start) >= duration { + break + } + } + + elapsed := time.Since(start).Seconds() + return float64(totalBytes) / elapsed // Bytes per second +} + +// Benchmarking + +func benchmark(task func(int), iterations int, cores int) float64 { + var wg sync.WaitGroup + wg.Add(cores) + start := time.Now() + + for i := 0; i < cores; i++ { + go func() { + task(iterations / cores) + wg.Done() + }() + } + + wg.Wait() + duration := time.Since(start).Seconds() + return float64(iterations) / duration // Return raw score +} + +func humanReadable(score float64, unit string) string { + units := []string{"", "K", "M", "G", "T"} + i := 0 + for score >= 1000 && i < len(units)-1 { + score /= 1000 + i++ + } + return fmt.Sprintf("%.2f %s%s", score, units[i], unit) +} + +func percentageDiff(current, baseline float64) string { + diff := (current - baseline) / baseline * 100 + return fmt.Sprintf("%+.2f%%", diff) +} + +// Encode results into a compact binary format +func encodeBaseline(results map[string]float64) string { + values := []float64{ + results["Integer Arithmetic-single"], results["Integer Arithmetic-multi"], + results["Floating Point Math-single"], results["Floating Point Math-multi"], + results["Sorting-single"], results["Sorting-multi"], + results["SHA-256 Hashing-single"], results["SHA-256 Hashing-multi"], + results["Compression-single"], + } + + buf := new(bytes.Buffer) + for _, v := range values { + // Scale down to save precision (e.g., fixed point) + scaled := int32(v / 1000) // Scale down by 1000 + binary.Write(buf, binary.LittleEndian, scaled) + } + return base64.StdEncoding.EncodeToString(buf.Bytes()) +} + +// Decode a compact binary baseline +func decodeBaseline(encoded string) (map[string]float64, error) { + data, err := base64.StdEncoding.DecodeString(encoded) + if err != nil { + return nil, err + } + + values := make([]float64, 9) + buf := bytes.NewReader(data) + for i := 0; i < 9; i++ { + var scaled int32 + err = binary.Read(buf, binary.LittleEndian, &scaled) + if err != nil { + return nil, err + } + values[i] = float64(scaled) * 1000 // Scale back up + } + + return map[string]float64{ + "Integer Arithmetic-single": values[0], "Integer Arithmetic-multi": values[1], + "Floating Point Math-single": values[2], "Floating Point Math-multi": values[3], + "Sorting-single": values[4], "Sorting-multi": values[5], + "SHA-256 Hashing-single": values[6], "SHA-256 Hashing-multi": values[7], + "Compression-single": values[8], + }, nil +} + +func main() { + iterations := 1_000_000 // Adjustable workload size + cores := runtime.NumCPU() + + workloads := map[string]func(int){ + "Integer Arithmetic": performIntegerArithmetic, + "Floating Point Math": performFloatingPointArithmetic, + "Sorting": performSorting, + "SHA-256 Hashing": performHashing, + } + + // Add compression workload with fixed duration + compressionDuration := 3 * time.Second // Fixed duration for compression test + fmt.Printf("\nCompression test duration: %s\n", compressionDuration) + + // Baseline comparison setup + var baseline map[string]float64 + if len(os.Args) > 1 { + var err error + baseline, err = decodeBaseline(os.Args[1]) + if err != nil { + fmt.Println("Error parsing baseline:", err) + os.Exit(1) + } + } + + // Results storage + results := make(map[string]float64) + + fmt.Println("Starting Extended CPU Benchmark...") + + for name, workload := range workloads { + fmt.Printf("\nRunning %s benchmark...\n", name) + + // Single-core benchmark + fmt.Println("Single-core performance:") + singleCoreScore := benchmark(workload, iterations, 1) + results[name+"-single"] = singleCoreScore + if baseline != nil { + fmt.Printf(" Single-core score: %s (%s)\n", + humanReadable(singleCoreScore, "ops/sec"), + percentageDiff(singleCoreScore, baseline[name+"-single"])) + } else { + fmt.Printf(" Single-core score: %s\n", humanReadable(singleCoreScore, "ops/sec")) + } + + // Multi-core benchmark + fmt.Println("Multi-core performance:") + multiCoreScore := benchmark(workload, iterations, cores) + results[name+"-multi"] = multiCoreScore + if baseline != nil { + fmt.Printf(" Multi-core score: %s (%s) using %d cores\n", + humanReadable(multiCoreScore, "ops/sec"), + percentageDiff(multiCoreScore, baseline[name+"-multi"]), + cores) + } else { + fmt.Printf(" Multi-core score: %s using %d cores\n", + humanReadable(multiCoreScore, "ops/sec"), cores) + } + } + + // Compression throughput + fmt.Println("\nRunning Compression throughput benchmark...") + singleCompressionScore := performCompressionThroughput(compressionDuration) + results["Compression-single"] = singleCompressionScore + fmt.Printf(" Single-core compression: %s\n", humanReadable(singleCompressionScore, "B/s")) + + // Output compact results for future runs + compactResults := encodeBaseline(results) + fmt.Printf("\nCompact results for future comparison: %s\n", compactResults) + + fmt.Println("\nExtended CPU Benchmark Completed.") +}