Linux 开发过程中I/O操作的效率测试

缘由:

在linux c/c++应用开发中,难免会产生大量的I/O,然而在对程序性能要求较高时,避免I/O过高或效率过低,导致整体性能拖慢。因此,在程序架构设计上要非常关注I/O带来的性能瓶颈,下面做一些简单的测试耗时,作为相关设计的参考。

目的:

1.性能分析的目的
1)找出系统性能瓶颈(包括硬件瓶颈和软件瓶颈);
2)提供性能优化的方案(升级硬件?改进系统系统结构?);
3)达到合理的硬件和软件配置;
4)使系统资源使用达到最大的平衡。(一般情况下系统良好运行的时候恰恰各项资源达到了一个平衡体,任何一项资源的过渡使用都会造成平衡体系破坏,从而造成系统负载极高或者响应迟缓。比如CPU过渡使用会造成大量进程等待CPU资源,系统响应变慢,等待会造成进程数增加,进程增加又会造成内存使用增加,内存耗尽又会造成虚拟内存使用,使用虚拟内存又会造成磁盘IO增加和CPU开销增加)
2.影响性能的因素
1)CPU(cpu的速度与性能很大一部分决定了系统整体的性能,是否使用SMP)
2)内存(物理内存不够时会使用交换内存,使用swap会带来磁盘I0和cpu的开销)
3)硬盘(存储系统)
a.Raid技术使用(RAID0, RAID1, RAID5, RAID0+1)
b.小文件读写瓶颈是磁盘的寻址(tps),大文件读写的性能瓶颈是带宽
c.Linux可以利用空闲内存作文件系统访问的cache,因此系统内存越大存储系统的性能也越好
4)网络带宽。
3.性能分析的步骤
1)对资源的使用状况进行长期的监控和数据采集(nagios、cacti)
2)使用常见的性能分析工具(vmstat、top、free、iostat等)
3)经验积累
a.应用程序设计的缺陷和数据库查询的滥用最有可能导致性能问题
b.性能瓶颈可能是因为程序差/内存不足/磁盘瓶颈,但最终表现出的结果就是CPU耗尽,系统负载极高,响应迟缓,甚至暂时失去响应
c.物理内存不够时会使用交换内存,使用swap会带来磁盘I0和cpu的开销
d.可能造成cpu瓶颈的问题:频繁执Perl,php,java程序生成动态web;数据库查询大量的where子句、order by/group by排序……
e.可能造成内存瓶颈问题:高并发用户访问、系统进程多,java内存泄露……
f.可能造成磁盘IO瓶颈问题:生成cache文件,数据库频繁更新,或者查询大表……
4.vmstat详细介绍
vmstat是一个很全面的性能分析工具,可以观察到系统的进程状态、内存使用、虚拟内存使用、磁盘的IO、中断、上下文切换、CPU使用等。对于 Linux 的性能分析,100%理解 vmstat 输出内容的含义,并能灵活应用,那对系统性能分析的能力就算是基本掌握了。
下面是vmstat命令的输出结果:
[root@monitor-www ~]# vmstat 1 5
procs —————memory————— ——swap—— ——io—— ——system—— ——cpu——
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 84780 909744 267428 1912076 0 0 20 94 0 0 2 1 95 1 0
1 2 84780 894968 267428 1912216 0 0 0 1396 2301 11337 8 3 89 0 0
1 0 84780 900680 267428 1912340 0 0 76 1428 1854 8082 7 2 90 0 0
1 0 84780 902544 267432 1912548 0 0 116 928 1655 7502 7 2 92 0 0
2 0 84780 900076 267432 1912948 0 0 180 904 1963 8703 10 3 87 0 0
对输出解释如下:
1)procs
a.r列表示运行和等待CPU时间片的进程数,这个值如果长期大于系统CPU个数,就说明CPU资源不足,可以考虑增加CPU;
b.b列表示在等待资源的进程数,比如正在等待I/O或者内存交换等。
2)memory
a.swpd列表示切换到内存交换区的内存数量(以KB为单位)。如果swpd的值不为0或者比较大,而且si、so的值长期为0,那么这种情况一般不用担心,不会影响系统性能;
b.free列表示当前空闲的物理内存数量(以KB为单位);
c.buff列表示buffers cache的内存数量,一般对块设备的读写才需要缓冲;
d.cache列表示page cached的内存数量,一般作文件系统的cached,频繁访问的文件都会被cached。如果cached值较大,就说明cached文件数较多。如果此时IO中的bi比较小,就说明文件系统效率比较好。
3)swap
a.si列表示由磁盘调入内存,也就是内存进入内存交换区的数量;
b.so列表示由内存调入磁盘,也就是内存交换区进入内存的数量
c.一般情况下,si、so的值都为0,如果si、so的值长期不为0,则表示系统内存不足,需要考虑是否增加系统内存。
4)IO
a.bi列表示从块设备读入的数据总量(即读磁盘,单位KB/秒)
b.bo列表示写入到块设备的数据总量(即写磁盘,单位KB/秒)
这里设置的bi+bo参考值为1000,如果超过1000,而且wa值比较大,则表示系统磁盘IO性能瓶颈。
5)system
a.in列表示在某一时间间隔中观察到的每秒设备中断数;
b.cs列表示每秒产生的上下文切换次数。
上面这两个值越大,会看到内核消耗的CPU时间就越多。
6)CPU
a.us列显示了用户进程消耗CPU的时间百分比。us的值比较高时,说明用户进程消耗的CPU时间多,如果长期大于50%,需要考虑优化程序啥的。
b.sy列显示了内核进程消耗CPU的时间百分比。sy的值比较高时,就说明内核消耗的CPU时间多;如果us+sy超过80%,就说明CPU的资源存在不足。
c.id列显示了CPU处在空闲状态的时间百分比;
d.wa列表示IO等待所占的CPU时间百分比。wa值越高,说明IO等待越严重。如果wa值超过20%,说明IO等待严重。
e.st列一般不关注,虚拟机占用的时间百分比。
其他分析工具:
iostat 、top、free等。
1. 此次测试样本:
本地文件读、写;
libxml2读写文件;
数据库本地insert\update\delete\select性能;
数据库网络insert\update\delete\select性能;
2.内存分配、字符串拷贝
内存:
在C/C++编程中,动态内存分配较难避免。使用过程中一定要成对使用malloc,free,new,delete防止内存泄露。
防止大量的分配大的内存和频繁的分配小的内存,操作内存碎片较多;
下面是分配不同大小内存情况的耗时情况:
1 kB: 0.404000 ms
10 kB: 0.397000 ms
1 MB: 32.260000 ms
10 MB: 32.519000 ms
512 MB: 43.178000 ms
1024 MB: 58.140000 ms
字符串:
memset:参考http://blog.csdn.net/yunhua_lee/article/details/6381866
建议不要大于1K的字符串进行此类操作;
借用他两张图:
直接调用memset
这里写图片描述
memcpy:
借用两张图:
这里写图片描述
3. 文件的读写
参考一处代码:http://blog.csdn.net/penzchan/article/details/18660307

/****************************************************************
* 说明: 用不同的方法,测试写文件的速度,测试结果表明
*       改变COUNT的值,将改变写入文件的大小
*      测试CPU使用率方法: /usr/bin/time -f "CPU: %P" ./a.out 1 
* ************************************************************/
#include <cstdio>
#include <time.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <malloc.h>
#include <sys/time.h>
using namespace std;
#define WRITE_FILE        /*定义这个宏,则把数据写到文件,否则不写,用于测试不写文件用的时间*/
const unsigned short usPageSize = 4*1024;            /*4K*/
const unsigned long STR_LEN = (usPageSize*1024) +1;      /*每次缓存4M有效数据写入文件 ,最后一个字节保证 null-terminated ,不写入文件*/
const unsigned long COUNT = 1;         /*改变COUNT的值,将改变写入文件的大小 256 --->1G  16 ---> 64M 请问 为什么512 2G出现总线错误?  */
char g_strUserFlow[2048] ;
/****************************************************************
* 功能: 用fprintf,测试写文件速度
* ************************************************************/
void fprintf_write1();
/****************************************************************
* 功能: 用fwrite,(使用系统缓存)测试写文件速度
* ************************************************************/
void fwrite_write2();
/****************************************************************
* 功能: 用fwrite(自己分配4M缓存,每次写入4M, 然后fflush),测试写文件速度
* ************************************************************/
void fwrite_write2_1();
/****************************************************************
* 功能: 用write, 设O_DIRECT,自己维护缓存, ,测试写文件速度
* ************************************************************/
void write_direct3();
/****************************************************************
* 功能: 用write,(使用系统缓存),测试写文件速度
* ************************************************************/
void write_write4();
/****************************************************************
* 功能: 用write,(自己分配4M缓存,每次写入4M, 每次fsync),测试写文件速度
* ************************************************************/
void write_write4_1();
/****************************************************************
* 功能: 用mmap每次映射4M内存,测试写文件速度
* ************************************************************/
void mmap_write5();
/****************************************************************
* 功能: 用mmap每次一次性映射全部文件,测试写文件速度
* ************************************************************/
void mmap_write5_1();
/****************************************************************
* 功能: 用mmap每次映射1M内存,测试写文件速度
* ************************************************************/
void mmap_write5_2();
/****************************************************************
* 功能: 用mmap每次映射2M内存,测试写文件速度
* ************************************************************/
void mmap_write5_3();
//void cout_write8();
void setRecordData(char *pStrBuf, unsigned long ulBufSize, char *pStrLeftDataBuf, unsigned short &usDataBufSize);
int main(int argc, char *argv[])
{
    int iFlowLen;
    int iNum = 1;

    if(2==argc && 0==strcmp("--help", argv[1]))
    {
      printf("\nusage:"
              "\n\t run all :              ./a.out "
          "\n\t run fprintf_write1():  ./a.out 1"   
                "\n\t run fwrite_write2():   ./a.out 2"  
                "\n\t run fwrite_write2_1(): ./a.out 2.1" 
                "\n\t run write_direct3():   ./a.out 3"  
                "\n\t run write_write4():    ./a.out 4" 
                "\n\t run write_write4_1():  ./a.out 4.1" 
                "\n\t run mmap_write5():     ./a.out 5" 
                "\n\t run mmap_write5_1():   ./a.out 5.1" 
                "\n\t run mmap_write5_2():   ./a.out 5.2" 
                "\n\t run mmap_write5_3():   ./a.out 5.3\n" 
       );
      exit(0); 
    } 
    if(3==argc)
    {
      iNum = atoi(argv[2]);
    }

    iFlowLen = sprintf(g_strUserFlow, 
     "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s"
   "\t%s\t%s\t%s\t\n",

   "1319618698.0", "2011-10-26 16:44:58", "1319618697.0", "1319618698.0", "460030919115059",
   "00a000002266f525", "", "", "Q d 8613309117677", "59",
   "2", "0", "1", " -1", "G02",
   "S38", "-1", "-1", "0", "-1",
   "-1", "123", "115.168.25.12", "172.26.187.5", "366B0004",
   "366B0004413E", "10.173.8.248", "10.0.0.200", "6", "52042",
   "80", "102", "3000000", "14", "14",
   "-", "-", "1", "8", "7",
   "1362", "5230", "1362", "5230", "0",
   "0", "0", "0", "0", "s.image.wap.soso.com",

   "http://s.image.wap.soso.com/img/?p=320_416_0_0_0&src=httpFimg19.artxun.comap.g19.artxun.com2FsdaFoldimgFf0a22Ff0a27ad0c8fc34ca9758soso.com",
   "0", "0", " 0", " -",

   "-", "-", " -", "14", "14",
   "0", "wap1", "0", "-", " -",
   "-", "PDSN_02", "延安BSC2", "0", "0",
            "", "-1", "", "-1", "-1",
   "-1", "0", "-1", "1491300", "",
   "0", "a8:c000:6380:0:ac1a:ba04:8b00:0/1200:a8c0:63:8000:ac:1aba:48b:670","-");
    printf("filesize = %lu\n", COUNT*(STR_LEN-1));
#ifdef WRITE_FILE
    printf("define WRITE_FILE\n\n");
#else
    printf("not define WRITE_FILE\n\n");
#endif
  while(iNum--)
  {
    if(1==argc)
    {
      fprintf_write1();   
        fwrite_write2();
        fwrite_write2_1();
        write_direct3(); 
        write_write4();
        write_write4_1();
        mmap_write5();
        mmap_write5_1();
        mmap_write5_2();
        mmap_write5_3();
    }
     else if(1 == atof(argv[1]))
     {
       fprintf_write1();   
     }
     else if(2 == atof(argv[1]))
     {
       fwrite_write2();   
     }
     else if(2.1 == atof(argv[1]))
     {
       fwrite_write2_1();   
     }
     else if(3 == atof(argv[1]))
     {
       write_direct3();   
     }
     else if(4 == atof(argv[1]))
     {
       write_write4();   
     }
     else if(4.1 == atof(argv[1]))
     {
       write_write4_1();   
     }
     else if(5 == atof(argv[1]))
     {
       mmap_write5();   
     }
     else if(5.1 == atof(argv[1]))
     {
       mmap_write5_1();   
     }
     else if(5.2 == atof(argv[1]))
     {
       mmap_write5_2();   
     }
     else if(5.3 == atof(argv[1]))
     {
       mmap_write5_3();   
     }
   }


    //cout_write8();
}
double diffTime(struct timeval struStop, struct timeval struStart)
{
    return ( (double)((1000000.0*struStop.tv_sec + struStop.tv_usec) - (1000000.0*struStart.tv_sec + struStart.tv_usec)) )/1000000.0; 
}
void fprintf_write1()
{
    int i = 0;
    FILE *fp = NULL;
    struct timeval struStart;
    struct timeval struStop;
    char strData[1024+1] = {0};  
    gettimeofday(&struStart, NULL);
    unsigned long  ulStart = clock();  
    fp = fopen("data.txt", "w+");
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);
    for (i =0; i< COUNT*usPageSize ; i++)
    {
         setRecordData(strData, 1024+1, strLeftData, strSize);  // 每次写1024 ,'\0' 不写入
#ifdef WRITE_FILE
        fprintf(fp, "%s", strData);
#endif
    }
    fclose(fp);
    printf("fprintf_write1:\t %.3lf (clock time)\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}
void fwrite_write2()
{   
    int i = 0;
    FILE *fp = NULL;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;

    char strData[1024+1] = {0};  
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);


    gettimeofday(&struStart, NULL);
    ulStart = clock();
    fp = fopen("data.txt", "w+");
    for (i=0; i<COUNT*usPageSize; i++)
    {
        setRecordData(strData, 1024+1, strLeftData, strSize);
#ifdef WRITE_FILE
        fwrite(strData, 1024, 1, fp);
#endif
    }
    fclose(fp);
    printf("fwrite_write2:\t %.3lf (clock time),using system buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}

void fwrite_write2_1()   
{      
    //char *pTmp = NULL;
    int i;
    //int j;
    FILE *fp = NULL;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[STR_LEN] = {0};   //4M  
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);   

    gettimeofday(&struStart, NULL);
    ulStart = clock();
     fp = fopen("data.txt", "w+");
    if (NULL == fp)
    { 
        perror("Cannot open file : ");
        return; 
    }    
    for (i=0; i<COUNT; i++)
    {
        setRecordData(strData, STR_LEN , strLeftData, strSize);  
#ifdef WRITE_FILE
        fwrite(strData, STR_LEN-1, 1, fp);   // 每次写入4M
        fflush(fp);
#endif
    } 

    fclose(fp);
    printf("fwrite_write2_1: %.3lf (clock time), allocate 4M, every time fflush()\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
    return ;
}
void write_direct3()   
{ 
    //char strTmp[1024];

    //char *pTmp = NULL;
    int i;
    int j;
    int fd = -1, ret = -10; 
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;

    //char strData[STR_LEN] = {0};
    char *buf = NULL;
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);

    //buf = (char *)valloc(1024*usPageSize);   
    posix_memalign((void**)&buf, usPageSize, STR_LEN );
    //typedef char _aligned_char __attribute__ ((aligned (8192)));
    //_aligned_char buf[1024*usPageSize];    

    gettimeofday(&struStart, NULL);
    ulStart = clock();
    fd = open("data.txt", O_RDWR |O_CREAT|O_DIRECT, 00600);
    if (fd<0)
    { 
        perror("Cannot open file : ");
        return; 
    }    
    for (i=0; i<COUNT; i++)
    {
        memset(buf, 0, 1024*usPageSize);
        setRecordData(buf, STR_LEN, strLeftData, strSize);       
#ifdef WRITE_FILE
        write(fd, buf, STR_LEN-1); 
#endif
    }
    free(buf);    
    close(fd);
    printf("write_direct3:\t %.3lf (clock time),using O_DIRECT, allocate 4M\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
    return ;
}
void write_write4()
{
    int i = 0;
    int fd;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[1024+1] = {0};
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);


    gettimeofday(&struStart, NULL);
    ulStart = clock();
    fd = open("data.txt", O_CREAT | O_RDWR);
    for (i=0; i<COUNT*usPageSize; i++)
    {
        setRecordData(strData, 1024+1 , strLeftData, strSize);
#ifdef WRITE_FILE
        write(fd, strData, 1024);
#endif
    }
    close(fd);
    printf("write_write4:\t %.3lf (clock time), using system buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}
void write_write4_1()   
{     
    //char buf[1024*usPageSize]; //4M         
    int i;

    int fd = -1, ret = -10; 
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[STR_LEN] = {0};
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);

    //memset(buf, 0, 1024*usPageSize);

    gettimeofday(&struStart, NULL);
    ulStart = clock();
    fd = open("data.txt", O_RDWR |O_CREAT, 00600);
    if (fd<0)
    { 
        perror("Cannot open file : ");
        return; 
    }    
    for (i=0; i<COUNT; i++)
    {
        setRecordData(strData, STR_LEN , strLeftData, strSize);
#ifdef WRITE_FILE
        write(fd, strData, STR_LEN-1);   /*一次写4M*/
        fsync(fd);
#endif
    } 

    close(fd);
    printf("write_write4_1:\t %.3lf (clock time), alloc 4M buffer, every time using fsync()\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
    return ;
}
void mmap_write5()
{
    int i = 0, j = 0;
    char *pMap = NULL;
    int iPagesize;
    int fd;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[STR_LEN] = {0};
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);
    //iPagesize = getpagesize();  
    gettimeofday(&struStart, NULL);
    ulStart = clock();
    fd = open("data.txt",O_RDWR|O_CREAT,00600);
    ftruncate(fd,  COUNT*(STR_LEN-1));
#ifndef WRITE_FILE
    pMap = (char *)calloc(1, STR_LEN-1);
#endif
    for (i = 0; i < COUNT; i++)
    {
#ifdef WRITE_FILE
         pMap = (char *)mmap(0,STR_LEN-1, PROT_WRITE, MAP_SHARED, fd, i*(STR_LEN-1)); // 每次打开4M
         if(MAP_FAILED == pMap)
         {
             perror("mmap_write5 error mmap() :");
             return;
         }
         //ftruncate(fd,  i*(STR_LEN-1) + (STR_LEN-1) );

#endif
         setRecordData(strData, STR_LEN , strLeftData, strSize);
         memcpy(pMap , strData, STR_LEN-1);
#ifdef WRITE_FILE
         munmap(pMap, STR_LEN-1);
#endif
    }    
    close(fd);
#ifndef WRITE_FILE
    free(pMap);
#endif
    printf("mmap_write5:     %.3lf (clock time), mmap: 4M buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}
void mmap_write5_1()
{    
    int i = 0, j = 0;
    char *pMap = NULL;
    int iPagesize;
    int fd;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[STR_LEN] = {0};
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);


    //iPagesize = getpagesize();    
    gettimeofday(&struStart, NULL);
    ulStart = clock();
#ifndef WRITE_FILE
    pMap = (char *)calloc(1, 1024*usPageSize*COUNT);
    if(NULL==pMap)
    {
        printf("pMap calloc error\n\n");
        return;
    }
#endif
    fd = open("data.txt",O_RDWR|O_CREAT,00600);
#ifdef WRITE_FILE
    pMap = (char *)mmap(0,(STR_LEN-1)*COUNT, PROT_WRITE, MAP_SHARED, fd, 0); // 一次全部打开文件映射(内存要求)
    ftruncate(fd,  (STR_LEN-1)*COUNT );
#endif
    for (j=0;  j<COUNT; j++)
    {        
        setRecordData(strData, STR_LEN , strLeftData, strSize);
        memcpy(pMap + j*(STR_LEN-1), strData, STR_LEN-1);
    }
#ifdef WRITE_FILE
    munmap(pMap, (STR_LEN-1)*COUNT);
#endif
    close(fd);
#ifndef WRITE_FILE
    free(pMap);
#endif
    printf("mmap_write5_1:\t %.3lf (clock time), mmap: all buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}
void mmap_write5_2()
{
    int i = 0;
    char *pMap = NULL;
    int iPagesize;
    int fd;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[STR_LEN] = {0};
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData);
    gettimeofday(&struStart, NULL);
    ulStart = clock();
#ifndef WRITE_FILE
    pMap = (char *)calloc(1, (STR_LEN-1)/4);
#endif
    fd = open("data.txt",O_RDWR|O_CREAT,00600);
    ftruncate(fd,  COUNT*(STR_LEN-1));

    for (i = 0; i < 4*COUNT; i++)
    {
#ifdef WRITE_FILE
         pMap = (char *)mmap(0,(STR_LEN-1)/4, PROT_WRITE, MAP_SHARED, fd, i*(STR_LEN-1)/4); // 每次打开1M
         //ftruncate(fd,  i*(STR_LEN-1)/4 + (STR_LEN-1)/4 );
#endif
         setRecordData(strData, (STR_LEN-1)/4 +1 , strLeftData, strSize);
         memcpy(pMap , strData, (STR_LEN-1)/4);
#ifdef WRITE_FILE
         munmap(pMap, (STR_LEN-1)/4);
#endif
    }    
    close(fd);
#ifndef WRITE_FILE
    free(pMap);
#endif
    printf("mmap_write5_2:   %.3lf(clock time) (clock time), mmap: 1M buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}
void mmap_write5_3()
{
    int i = 0;
    char *pMap = NULL;
    int iPagesize;
    int fd;
    unsigned long  ulStart;
    struct timeval struStart;
    struct timeval struStop;
    char strData[STR_LEN] = {0};
    char strLeftData[2048] = {0};   
    unsigned short strSize = sizeof(strLeftData); 

    gettimeofday(&struStart, NULL);
    ulStart = clock();
#ifndef WRITE_FILE
    pMap = (char *)calloc(1, 512*usPageSize);
#endif
    fd = open("data.txt",O_RDWR|O_CREAT,00600);
    ftruncate(fd,  COUNT*(STR_LEN-1));

    for (i = 0; i < 2*COUNT; i++)
    {
#ifdef WRITE_FILE
         pMap = (char *)mmap(0,(STR_LEN-1)/2, PROT_WRITE, MAP_SHARED, fd, i*(STR_LEN-1)/2); // 每次打开2M
         //ftruncate(fd,  i*(STR_LEN-1)/2 + (STR_LEN-1)/2 );
#endif
         setRecordData(strData, (STR_LEN-1)/2 +1 , strLeftData, strSize);
         memcpy(pMap , strData, (STR_LEN-1)/2);
#ifdef WRITE_FILE
         munmap(pMap, (STR_LEN-1)/2);
#endif
    }    
    close(fd);
#ifndef WRITE_FILE
    free(pMap);
#endif
    printf("mmap_write5_3:     %.3lf (clock time), mmap: 2M buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
    gettimeofday(&struStop, NULL);
    printf("all time diff:   %.3lf\n\n", diffTime(struStop, struStart));
}
void setRecordData(char *pStrBuf, unsigned long ulBufSize, char *pStrLeftDataBuf, unsigned short &usDataBufSize)
{
    unsigned long ulLeftBufLen = ulBufSize;
    short sCopyLen = 0;
    unsigned short usLeftCharLen = 0;
    char *pStrBufTmp = pStrBuf;
    char *pStrTmp = pStrLeftDataBuf;
    if (NULL==pStrBuf || NULL==pStrLeftDataBuf)
    {
        return ;
    }   

    sCopyLen = snprintf(pStrBufTmp, ulLeftBufLen, pStrTmp);
    if(sCopyLen<0)
    {
        perror("snprintf error: ");
        return ;
    }
    if( sCopyLen < ulLeftBufLen-1 )
    {
        ulLeftBufLen = ulLeftBufLen - sCopyLen;
        pStrBufTmp += sCopyLen;
        pStrTmp = g_strUserFlow;
        while(ulLeftBufLen > 0)
        {
            sCopyLen = snprintf(pStrBufTmp, ulLeftBufLen, pStrTmp);
            if(sCopyLen<0)
            {
                perror("snprintf error: ");
                return;
            }
            if( sCopyLen < ulLeftBufLen-1 )
            {
                ulLeftBufLen = ulLeftBufLen - sCopyLen;
                pStrBufTmp += sCopyLen;
            }
            else
            {
                break;
            }
        }
    }
    /*剩下的拷到pStrLeftDataBuf*/
    strncpy(pStrLeftDataBuf, pStrTmp + (ulLeftBufLen-1), usDataBufSize-1 );  /*确保:pStrLeftDataBuf[usDataBufSize-1] = '\0'*/
}

测试结果:
文件小的情况下不到毫秒:
补充写4M的结果:
这里写图片描述

4. 数据库本地
insert操作也与数据库设计相关;
本地操作大概4MS左右。
5. 数据库网络
PLSQL:执行结果
这里写图片描述
OCCI insert语句耗时大概均值在16MS左右,有较小抖动;
6. 常见的I/O解决方案
根据软件架构,如果实时性较强,尽量要将IO进行分离;

个人总结,仅供参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值