write如何实现高速写盘


#define _GNU_SOURCE

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sched.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/stat.h>

//#define BUF_SIZE (128 * 1024 * 1024)
#define BUF_SIZE (128 * 1024 * 1024)
#define MEMCNT 1

int main(int argc, char* argv[])
{
	int fd;
	int i = 0;
	int j = 0;
	int ntimes = 0;
	char filename[128] = {0};
	unsigned char *p_buffer[MEMCNT];
	size_t PageSize = getpagesize();
	printf("pagesize=%d\n", PageSize);
	for( i = 0 ; i < MEMCNT ; i++ )
	{
		int ret = posix_memalign((void **)(&p_buffer[i]), PageSize, BUF_SIZE);
		if (ret) 
		{
			perror("posix_memalign failed");
			exit(1);
		}
	}  
	sprintf(filename, "/data/%02d", ntimes);
	printf("=================== test write file : %s ===================\n", filename);

	fd = open(filename, O_WRONLY|O_CREAT|O_DIRECT|O_LARGEFILE, 0755);
	//fd = open(filename, O_WRONLY|O_CREAT|O_DIRECT, 0755);
	if (fd < 0)
	{
		perror("open failed");
		close(fd);
		exit(1);
	}

	for(j =0;j<MEMCNT;j++)
	{
		for (i = 0; i < BUF_SIZE; ++i)
		{
			p_buffer[j][i] = i % 256;
		}
	}

	int cnt = 0;
	double AllTime= 0.0;
	int Write1GCnt = 0;
	j = 0;
	double SpeedVal = 0;
	while(1)
	{
		struct timeval start_t, end_t;
		double n_time = 0.0;
		gettimeofday(&start_t, NULL);
		write(fd, p_buffer[j], BUF_SIZE);
		usleep(20);
		cnt++;
		gettimeofday(&end_t, NULL);
		j++;
		if(j==MEMCNT)
		{
			j=0;
		}

		n_time = ((end_t.tv_sec - start_t.tv_sec)*1000*1000 + (end_t.tv_usec - start_t.tv_usec))/1000.0;
		AllTime+= n_time;
		if( cnt >= (1024*1024*1024/BUF_SIZE) )
		{
			Write1GCnt++;
			double Speed = 1024*1024*1024/AllTime/1000;
			SpeedVal += Speed - 400.0;
			if( SpeedVal > 0 )
			{
				SpeedVal = 0;
			}
			printf("AllTime = %lf ms, daikuan = %lf M/s  Write1GCnt = %dG  SpeedVal = %lfMB\n", AllTime, Speed , Write1GCnt , SpeedVal);
			cnt = 0;
			AllTime = 0;
		}
	}
	close(fd);
	free(p_buffer);
	return 0;
}

 需要使用以下的方式提高带宽

1.调用posix_memalign()函数申请连续的内存空间

int posix_memalign (void **memptr,
                    size_t alignment,
                    size_t size);

 

posix_memalign()函数和malloc这类函数的区别是它申请的内存为连续的。调用posix_memalign( )成功时会返回size字节的动态内存,并且这块内存的地址是alignment的倍数。参数alignment必须是2的幂,还是void指针的大小的倍数。返回的内存块的地址放在了memptr里面,函数返回值是0.

调用失败时,没有内存会被分配,memptr的值没有被定义,返回如下错误码之一:

EINVAL

参数不是2的幂,或者不是void指针的倍数。

ENOMEM

没有足够的内存去满足函数的请求。

要注意的是,对于这个函数,errno不会被设置,只能通过返回值得到。

2.使用getpagesize函数获得一页内存大小并以此大小为单位申请内存

系统给我们提供真正的内存时,用页为单位提供,一次最少提供一页的真实内存空间
 分配内存空间:你真实的分配了多少内存,就使用多少内存,不要越界使用
 但是系统提供的真实内存空间是以页来提供的。

3.weite的O_DIRECT和O_LARGEFILE参数

调用write时加上这两个参数,并使用较大的粒度写盘,如64M,128M,以提高带宽,总的来说,一半粒度越大,带宽越高。你可以根据自己的项目需求实际测试一下多大的粒度可以满足条件

最后使用dd指令dd if=/dev/zero of=/data/file.file bs=1M count=10000 oflag=direct实测SSD带宽接近600M/s左右,使用IOMeter软件实测写盘带宽800M/s左右,使用我们的函数测128M的粒度前150G可达到700M/s。前1T可达到400M/s,超过1T带宽接近400M/s。

这个速度是我们SSD的速度,各位还需根据自己的SSD实际测试。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值