glibc的 Asynchronous I/O 写性能测试

测试主机是AIX6.1

 

测试数据是向文件中顺序写入 8K * 50000 大小的数据,生成的文件大约为390M

 

测试对比了两种写操作,一种是aio_write, 另一种是 pwrite64; dwFlags 是open文件时,传入的参数

 

第一种测试

 

dwFlags = O_RDWR |  O_LARGEFILE | O_DIRECT | O_CREAT | O_EXCL;

 

pwrite64 时间 : 237 秒

aio_write 时间: 236 秒

 

 

 

第二种测试

 

dwFlags = O_RDWR |  O_LARGEFILE | O_SYNC  | O_CREAT | O_EXCL;

 

pwrite64 时间 : 560秒

aio_write 时间:  567秒

 

 

第三种测试

 

dwFlags = O_RDWR | O_LARGEFILE | O_DIRECT | O_SYNC  | O_CREAT | O_EXCL;

 

pwrite64 时间 : 568秒

aio_write 时间:  569秒

 

 

由于测试只是测试写操作,而且是顺序写,没有随机写;另一方面,没有在写操作中,加入写读作;还有就是只是对单一文件的写操作,不是多线程同时对多个文件的操作,所以测试还有很多局限性,更详细的测试需要进一步完成,还需测试不同页面大小时对性能的影响

 

从上面这三种测试来看,

第一,当 dwFlags 相同时, 在单文件上面,同步写(pwrite64 )和异步写(aio_write )差距不大,主要原因估计是glibc的底层实现也是通过pwrite64 实现的,只不过加了一个多线程,也许对多个文件时,会有一些差别。

 

 

第二,O_DIRECT 比 O_SYNC  比较大的提高写性能,快了一半,

 

第三,O_SYNC  与 O_DIRECT | O_SYNC  几乎相同,

 

 

下面是测试用的程序

 

 

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <aio.h>
#include <string.h>
#include <errno.h>

typedef char _aligned_char __attribute__ ((aligned (8192)));

const int DATA_LEN = 8192;
const int DATA_SIZE = 50000;

 //_aligned_char bufferAO[8192];
 
 char bufferAO[8192] __attribute__((aligned(4096)));

void testAIO()
{
    struct timeval start;
    struct timeval end;
    int ret;
   
    //_aligned_char buffer[DATA_LEN];
   
    int i = 0;
   
    struct aioinit;

   

  int dwFlags = O_RDWR | O_LARGEFILE | O_DIRECT | O_SYNC  | O_CREAT | O_EXCL;  //| O_NOATIME
  
  dwFlags = O_RDWR |  O_LARGEFILE | O_SYNC  | O_CREAT | O_EXCL;
  
  //aioinit.aio_threads = 10;
  //aioinit.aio_num = 10;
  //aio_init(&aioinit);
  
  int fd = open("aio_write.dat", dwFlags);
    if (fd<0)
    {
        perror("open error:");
        return;
    }
   
    if (ftruncate64(fd, DATA_LEN * DATA_SIZE))
    {
      perror("ftruncate64 error:");
        return;
    }


    gettimeofday(&start, NULL);
   
   
   
    for (; i<= DATA_SIZE; i++)
    {
     struct aiocb stAio;
     memset(&stAio, 0, sizeof(stAio));
     stAio.aio_buf = bufferAO;
     stAio.aio_nbytes = DATA_LEN;
     stAio.aio_offset = i * DATA_LEN;
     stAio.aio_fildes = fd;
    
     ret = aio_write(&stAio);
    
     if(ret < 0)
     {
      perror("aio_write error:");
        return;
     }
    
     struct aiocb *cblist[1] = {&stAio};

   ret = aio_error(&stAio);
 

   if (ret == 0) {

   // already completed

   }
   else if (ret == EINPROGRESS) {
    if (aio_suspend((const struct aiocb *const*)cblist, 1, NULL))
    {
       perror("aio_suspend error:");
         return;
      }
   }
   else {
    perror("aio_error error:");
         return;
   }

  if (aio_return(&stAio) != DATA_LEN)
   {
    perror("aio_return error:");
        return;
      }
    }
   
    gettimeofday(&end, NULL);
   
    close(fd);
   
    printf("/nAIO O_DIRECT second : %d microSec : %d/n", end.tv_sec-start.tv_sec, end.tv_usec-start.tv_usec);
}

 


void test()
{
    struct timeval start;
    struct timeval end;
    int ret;
   
    //_aligned_char buffer[DATA_LEN];
   
    int i = 0;
   
  int dwFlags = O_RDWR | O_LARGEFILE | O_DIRECT | O_SYNC  | O_CREAT | O_EXCL; //| O_NOATIME
  
  dwFlags = O_RDWR |  O_LARGEFILE | O_SYNC  | O_CREAT | O_EXCL;
  
  int fd = open("write.dat", dwFlags);
    if (fd<0)
    {
        perror("open error:");
        return;
    }
  
  if (ftruncate64(fd, DATA_LEN * DATA_SIZE))
    {
      perror("ftruncate64 error:");
        return;
    }
  
    gettimeofday(&start, NULL);
   
    for (; i<= DATA_SIZE; i++)
    {
     //int nLen = write(fd, bufferAO, DATA_LEN);
     int nLen = pwrite64(fd, bufferAO, DATA_LEN, i*DATA_LEN );
     
     if (nLen<DATA_LEN)
     {
         perror("write error:");
         return;
     }

    }
   
    gettimeofday(&end, NULL);
   
    close(fd);
   
    printf("/nnoAio second : %d microSec : %d/n", end.tv_sec-start.tv_sec, end.tv_usec-start.tv_usec);
}


int main()
{
    test();
    testAIO();
    return 1;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值