Add vectored read to readbenchfs
You can now run `./readbenchfs --mount_point dir --vectored` and then `dd if=dir/test of=/dev/null iflag=direct bs=1M status=progress` to test vectored read speed. Results from my laptop (Linux 5.10): 1 core (GOMAXPROCS=1): - Before vectored read patch: 2.1 GB/s - Non-vectored read after vectored read patch: 2.1 GB/s - Vectored read: 2.8 GB/s All cores: - Before vectored read patch: 3.0 GB/s - Non-vectored read after vectored read patch: 3.3 GB/s - Vectored read: 5.9 GB/sgeesefs-0-31-3
parent
c818f6216b
commit
84920d11dd
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
var fMountPoint = flag.String("mount_point", "", "Path to mount point.")
|
var fMountPoint = flag.String("mount_point", "", "Path to mount point.")
|
||||||
var fReadOnly = flag.Bool("read_only", false, "Mount in read-only mode.")
|
var fReadOnly = flag.Bool("read_only", false, "Mount in read-only mode.")
|
||||||
|
var fVectored = flag.Bool("vectored", false, "Use vectored read.")
|
||||||
var fDebug = flag.Bool("debug", false, "Enable debug logging.")
|
var fDebug = flag.Bool("debug", false, "Enable debug logging.")
|
||||||
var fPprof = flag.Int("pprof", 0, "Enable pprof profiling on the specified port.")
|
var fPprof = flag.Int("pprof", 0, "Enable pprof profiling on the specified port.")
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ func main() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := readbenchfs.NewReadBenchServer()
|
server, err := readbenchfs.NewReadBenchServer(*fVectored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("makeFS: %v", err)
|
log.Fatalf("makeFS: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +38,8 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &fuse.MountConfig{
|
cfg := &fuse.MountConfig{
|
||||||
ReadOnly: *fReadOnly,
|
ReadOnly: *fReadOnly,
|
||||||
|
UseVectoredRead: *fVectored,
|
||||||
}
|
}
|
||||||
|
|
||||||
if *fDebug {
|
if *fDebug {
|
||||||
|
|
|
@ -27,7 +27,8 @@ import (
|
||||||
|
|
||||||
type readBenchFS struct {
|
type readBenchFS struct {
|
||||||
fuseutil.NotImplementedFileSystem
|
fuseutil.NotImplementedFileSystem
|
||||||
buf []byte
|
buf []byte
|
||||||
|
useVectoredRead bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 TB
|
// 1 TB
|
||||||
|
@ -35,14 +36,13 @@ const fileSize = 1024 * 1024 * 1024 * 1024
|
||||||
|
|
||||||
var _ fuseutil.FileSystem = &readBenchFS{}
|
var _ fuseutil.FileSystem = &readBenchFS{}
|
||||||
|
|
||||||
// Create a file system that mirrors an existing physical path, in a readonly mode
|
func NewReadBenchServer(useVectoredRead bool) (server fuse.Server, err error) {
|
||||||
|
|
||||||
func NewReadBenchServer() (server fuse.Server, err error) {
|
|
||||||
// 1 GB of random data to exceed CPU cache
|
// 1 GB of random data to exceed CPU cache
|
||||||
buf := make([]byte, 1024*1024*1024)
|
buf := make([]byte, 1024*1024*1024)
|
||||||
rand.Read(buf)
|
rand.Read(buf)
|
||||||
server = fuseutil.NewFileSystemServer(&readBenchFS{
|
server = fuseutil.NewFileSystemServer(&readBenchFS{
|
||||||
buf: buf,
|
buf: buf,
|
||||||
|
useVectoredRead: useVectoredRead,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ func (fs *readBenchFS) ReadFile(ctx context.Context, op *fuseops.ReadFileOp) err
|
||||||
if op.Offset > fileSize {
|
if op.Offset > fileSize {
|
||||||
return io.EOF
|
return io.EOF
|
||||||
}
|
}
|
||||||
end := op.Offset + int64(len(op.Dst))
|
end := op.Offset + op.Size
|
||||||
if end > fileSize {
|
if end > fileSize {
|
||||||
end = fileSize
|
end = fileSize
|
||||||
}
|
}
|
||||||
|
@ -134,10 +134,13 @@ func (fs *readBenchFS) ReadFile(ctx context.Context, op *fuseops.ReadFileOp) err
|
||||||
if e-s > end-pos {
|
if e-s > end-pos {
|
||||||
e = s + end - pos
|
e = s + end - pos
|
||||||
}
|
}
|
||||||
copy(op.Dst[pos-op.Offset:], fs.buf[s:])
|
if fs.useVectoredRead {
|
||||||
|
op.Data = append(op.Data, fs.buf[s:e])
|
||||||
|
} else {
|
||||||
|
copy(op.Dst[pos-op.Offset:], fs.buf[s:])
|
||||||
|
}
|
||||||
pos = op.Offset + e
|
pos = op.Offset + e
|
||||||
}
|
}
|
||||||
//op.Data = [][]byte{ contents[op.Offset : end] }
|
|
||||||
op.BytesRead = int(end - op.Offset)
|
op.BytesRead = int(end - op.Offset)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue