
CPU가 메모리의 한 영역에서 다른 영역으로 데이터를 복사하는 작업을 최소화하거나 피하는 작업
웹 애플리케이션에서 정적 콘텐츠를 제공한다는 것은?
데이터가 kernel-user 경계를 넘어다닐 때마다 copy가 일어나므로 CPU와 memory가 소모된다.


zero-copy를 사용하는 애플리케이션은 kernel이 애플리케이션 통하지 않고 disk 파일에서 socket으로 직접 데이터를 복사하도록 요청한다.
애플리케이션 성능을 크게 향상시키고 kernel-user 모드 간 context switching 횟수를 줄여준다.


func copyWithoutZeroCopy(sourceFile, destinationFile string) {
source, err := os.Open(sourceFile)
if err != nil {
panic(err)
}
defer source.Close()
destination, err := os.Create(destinationFile)
if err != nil {
panic(err)
}
defer destination.Close()
bufferSize := 1024
buffer := make([]byte, bufferSize)
for {
n, err := source.Read(buffer)
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
_, err = destination.Write(buffer[:n])
if err != nil {
panic(err)
}
}
}
func copyWithZeroCopy(sourceFile, destinationFile string) {
source, err := os.Open(sourceFile)
if err != nil {
panic(err)
}
defer source.Close()
destination, err := os.Create(destinationFile)
if err != nil {
panic(err)
}
defer destination.Close()
_, err = io.Copy(destination, source)
if err != nil {
panic(err)
}
}
func BenchmarkCopyWithoutZeroCopy(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
copyWithoutZeroCopy(sourceFile, destinationWithoutZeroCopy)
}
}
func BenchmarkCopyWithZeroCopy(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
copyWithZeroCopy(sourceFile, destinationWithZeroCopy)
}
}
| filesize(bytes) | non-zero-copy | zero-copy |
|---|---|---|
| 8 | 59832 ns/op | 53925 ns/op |
| 747315 | 2321734 ns/op | 369461 ns/op |
대량의 데이터를 복사하는 애플리케이션에서는 zero-copy 기법이 높은 성능 향상을 제공하는 것을 확인했다.