细说Go使用DirectIO

细说Go使用DirectIO

一。DirectIO的要求

在Go语言中,要进行DirectIO(简称DIO),要满足以下要求:

  1. open()的时候加入O_DIRECT标记
  2. 缓冲区([]byte)要是512字节内存对齐
  3. 缓冲区([]byte)的大小要是512的倍数

第一个和第三个要求很容易做到,下面重点看第二个要求如何实现

二。创建一个512字节对齐的缓冲区([]byte)

什么内存对齐

什么是“512字节内存对齐”?

简单来说,就是[]byte的第一个元素的地址能被512整除。

判断一个数能否被另一个数整除,很简单,就是使用取模运算%求余数即可,所以我们可以写出下面的函数用来判断一个地址是否512对齐:

func IsAlign(buf []byte, align int) bool {
	return uintptr(unsafe.Pointer(&buf[0])) % uintptr(align) == 0
}

其中uintptr(unsafe.Pointer(xxx))这段,只是做类型转换,使得xxx能被用来做取模运算而已。

这行代码在数学上没有问题,但是在运行效率上我们可以做的更好:当align参数是2的倍数的时候,求余运算可以简化成&运算,所以上面的函数可以改进成这样:

func IsAlign(buf []byte, align int) bool {
	return uintptr(unsafe.Pointer(&buf[0])) & uintptr(align-1) == 0
}

创建一个512对齐的[]byte

经过上面的努力,我们有个手段可以判断一个地址是否512对齐,接下来我们就要利用它来产生一个512对齐的[]byte

当我们创建一个普通的byte切片的时候,它的开始地址(第一个元素的地址)是随机的:

make([]byte, 128)

要想创建一个指定对齐地址的[]byte,语言层面没有给出办法,所以我们要饶一下:

假设系统给我们产生的地址是A,那么我在[A, A+512)的范围内,挨个地址去寻找,必定能找到一个地址它是512地址对齐的。

所以我们可以写个for循环,不停对A+1,然后判断它是否对齐,再+1,周而复始。

但这样也太没效率了,我们可以改进一下:既然我们能很快算出余数,那么,我让A加上(512-余数),不就直接得到那个对齐的地址来吗?

这就是最终函数:

func MakeAlignBuf(size int, align int) []byte {
	buf := make([]byte, size+align)

	a := int(uintptr(unsafe.Pointer(&buf[0])) & uintptr(align-1))
	offset := 0
	if a != 0 {
		offset = align - a
	}
	buf = buf[offset : offset+size]

	return buf
}

三。进行directIO

func main() {
	file, err := os.OpenFile("/mnt/ext4/dio.txt", syscall.O_DIRECT|os.O_CREATE|os.O_WRONLY, 0644) // 满足DIO要求1
	if err != nil {
		fmt.Println("OpenFile() failed")
		return
	}
	defer file.Close()

	buf := MakeAlignBuf(1024, 512) // 满足DIO要求2和3
	if !IsAlign(buf, 512) {
		fmt.Println("Buf not aligned")
		return
	}

	copy(buf, []byte("hello world\n"))
	_, err = file.Write(buf)
	if err != nil {
		fmt.Println("write error: ", err.Error())
	}
}

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值