optimize performance: reduce allocations, buffered I/O, and zero-copy reads
- Read path: eliminate redundant allocation in bsPerformCommand - remove the pre-allocation before bs.Read() and the append loop for zero-fill, use direct copy and in-place zero-fill instead - parseHeader: use command pool (getCommand) instead of direct allocation, reducing GC pressure on the hot path - Unmap: use a shared 1MB zero buffer instead of allocating per-descriptor, dramatically reducing allocations for large unmap operations - Network I/O: add 256KB bufio.Writer to iSCSI connections, batching small PDU writes into fewer syscalls. Flush after txHandler completes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -159,11 +159,26 @@ func (bs *FileBackingStore) DataAdvise(offset, length int64, advise uint32) erro
|
||||
return util.Fadvise(bs.file, offset, length, advise)
|
||||
}
|
||||
|
||||
// unmapZeroBufSize is the size of the reusable zero buffer for unmap operations.
|
||||
const unmapZeroBufSize = 1 << 20 // 1MB
|
||||
|
||||
// unmapZeroBuf is a pre-allocated zero buffer shared across unmap calls.
|
||||
var unmapZeroBuf = make([]byte, unmapZeroBufSize)
|
||||
|
||||
func (bs *FileBackingStore) Unmap(descriptors []api.UnmapBlockDescriptor) error {
|
||||
for _, desc := range descriptors {
|
||||
zeros := make([]byte, desc.TL)
|
||||
if _, err := bs.file.WriteAt(zeros, int64(desc.Offset)); err != nil {
|
||||
return err
|
||||
remaining := desc.TL
|
||||
off := int64(desc.Offset)
|
||||
for remaining > 0 {
|
||||
writeLen := remaining
|
||||
if writeLen > unmapZeroBufSize {
|
||||
writeLen = unmapZeroBufSize
|
||||
}
|
||||
if _, err := bs.file.WriteAt(unmapZeroBuf[:writeLen], off); err != nil {
|
||||
return err
|
||||
}
|
||||
off += int64(writeLen)
|
||||
remaining -= writeLen
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user