#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实际测试。