wip: 重新整理 install cmd
This commit is contained in:
144
pkg/syscheck/mem.go
Normal file
144
pkg/syscheck/mem.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package syscheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// GetMemorySpace returns total physical memory (RAM) in bytes, excluding swap
|
||||
func GetMemorySpace(ctx context.Context) (int64, error) {
|
||||
var info unix.Sysinfo_t
|
||||
if err := unix.Sysinfo(&info); err != nil {
|
||||
return 0, fmt.Errorf("failed to get memory info: %w", err)
|
||||
}
|
||||
|
||||
// Total physical RAM (excluding swap)
|
||||
// info.Totalram is in memory unit size (info.Unit)
|
||||
totalMemory := int64(info.Totalram) * int64(info.Unit)
|
||||
return totalMemory, nil
|
||||
}
|
||||
|
||||
// GetMemorySpeed measures memory read/write speed by allocating and accessing memory
|
||||
// Returns read speed and write speed in bytes per second
|
||||
func GetMemorySpeed(ctx context.Context) (int64, int64, error) {
|
||||
const (
|
||||
testSize = 512 * 1024 * 1024 // 512MB test size
|
||||
iterations = 5 // Number of iterations for averaging
|
||||
)
|
||||
|
||||
// Test write speed
|
||||
writeSpeed, err := measureMemoryWriteSpeed(ctx, testSize, iterations)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to measure memory write speed: %w", err)
|
||||
}
|
||||
|
||||
// Test read speed
|
||||
readSpeed, err := measureMemoryReadSpeed(ctx, testSize, iterations)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to measure memory read speed: %w", err)
|
||||
}
|
||||
|
||||
return readSpeed, writeSpeed, nil
|
||||
}
|
||||
|
||||
// measureMemoryWriteSpeed measures memory write speed
|
||||
func measureMemoryWriteSpeed(ctx context.Context, size int64, iterations int) (int64, error) {
|
||||
var totalDuration time.Duration
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
// Check context cancellation
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
// Allocate memory buffer
|
||||
buffer := make([]byte, size)
|
||||
|
||||
// Generate random data
|
||||
source := make([]byte, 1024*1024) // 1MB source buffer
|
||||
if _, err := rand.Read(source); err != nil {
|
||||
return 0, fmt.Errorf("failed to generate random data: %w", err)
|
||||
}
|
||||
|
||||
// Start timing
|
||||
startTime := time.Now()
|
||||
|
||||
// Write data to memory buffer
|
||||
for offset := int64(0); offset < size; offset += int64(len(source)) {
|
||||
remaining := size - offset
|
||||
if remaining < int64(len(source)) {
|
||||
copy(buffer[offset:], source[:remaining])
|
||||
} else {
|
||||
copy(buffer[offset:offset+int64(len(source))], source)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop timing
|
||||
duration := time.Since(startTime)
|
||||
totalDuration += duration
|
||||
|
||||
// Force the buffer to be used to prevent optimization
|
||||
_ = buffer[0]
|
||||
}
|
||||
|
||||
// Calculate average speed
|
||||
avgDuration := totalDuration / time.Duration(iterations)
|
||||
speed := int64(float64(size) / avgDuration.Seconds())
|
||||
|
||||
return speed, nil
|
||||
}
|
||||
|
||||
// measureMemoryReadSpeed measures memory read speed
|
||||
func measureMemoryReadSpeed(ctx context.Context, size int64, iterations int) (int64, error) {
|
||||
var totalDuration time.Duration
|
||||
|
||||
// Pre-allocate and fill buffer
|
||||
buffer := make([]byte, size)
|
||||
if _, err := rand.Read(buffer); err != nil {
|
||||
return 0, fmt.Errorf("failed to initialize buffer: %w", err)
|
||||
}
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
// Check context cancellation
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
// Start timing
|
||||
startTime := time.Now()
|
||||
|
||||
// Read data from memory buffer
|
||||
var sum int64
|
||||
for offset := int64(0); offset < size; offset += 1024 {
|
||||
// Read in chunks to simulate real access patterns
|
||||
end := offset + 1024
|
||||
if end > size {
|
||||
end = size
|
||||
}
|
||||
for j := offset; j < end; j++ {
|
||||
sum += int64(buffer[j])
|
||||
}
|
||||
}
|
||||
|
||||
// Stop timing
|
||||
duration := time.Since(startTime)
|
||||
totalDuration += duration
|
||||
|
||||
// Use sum to prevent optimization
|
||||
_ = sum
|
||||
}
|
||||
|
||||
// Calculate average speed
|
||||
avgDuration := totalDuration / time.Duration(iterations)
|
||||
speed := int64(float64(size) / avgDuration.Seconds())
|
||||
|
||||
return speed, nil
|
||||
}
|
||||
Reference in New Issue
Block a user