libeio性能テスト


前言:
前に検索したところ、libeioの読み書き性能テストに関するデータがないようなので、直接テストプログラムを書いてテストしました.
書いたものは試していないし、インターフェースもあるので、必要があれば自分で記入してもいいです.
libeioについて:
これはライブラリです
Marc Lehmann
書いた、この大牛について、興味のある人は探してもいいです.
テストについて
テスト環境は私はそれぞれABCで表して、ランダムにファイルの中のある位置の始まりの一定の長さを読みます
Aは私の仮想マシンの中のテストを表して、テストディレクトリの中のデータの大きさによって異なって、明らかな違いをもたらします
Bはサーバ1でのテストを示し、テストのディレクトリは200以上のflvファイルを格納するルートディレクトリであり、ファイルが小さいため、速度が速い
Cはサーバー2の中のテストを表して、テストの目次は実際のオンラインサーバーの中の数千の映画とテレビのデータのルートの目次で、すべての映画とテレビのデータは1 Tディスクの空間に近いことを占めて、ファイルが大きいため、また一定の時間間隔を隔てて同期のデータの影響があって、およびシステムの中のいくつかのその他のパラメータの影響があって、だからテストのファイルの個数は1000個を選びます.速度交差Bのテスト結果はかなり遅い.
            
テスト結果:
        A:
1)大きいファイルがあるデータを選択し、ディレクトリにファイルが少ない場合、テスト構造は280ぐらいのM/sに達することができる.
2)解凍圧縮パッケージが保存されている任意のディレクトリを選択し、ディレクトリ内のファイルは9000個以上あり、ファイルは小さく、テスト速度は31.247337 M/sに達する.
B:この環境は比較的に簡単で、直接テストの結果を貼ります
all file list size:223
src file list size:223
 dst_file_list_size:223
buf list is full out
test end,read size:21766.363750M cost:83.639529,speed:260.240152M/s
        C:
1)実際の映像データディレクトリのサブディレクトリを選択し、ファイル数は300個以上で、テスト結果は以下の通りである.
use pointer dir:/data/data2/
test begin
all file list size:329
src file list size:329
 dst_file_list_size:329
test end,read size:3942.934089M cost:14.385984,speed:274.081640M/s
2)すべての映画・テレビデータのルート・ディレクトリを選択し、ファイル数は万個近くあり、システム関係のため、数万個を開いて会カードの持ち主をテストする.
したがって、1000個のファイルを選択し、テスト結果は次のとおりです.
最初の結果:
use pointer dir:/data/
test begin
all file list size:7803
src file list size:7796
 dst_file_list_size:7796
test end,read size:11804.820662M cost:65.706916,speed:179.658724M/s
2回目の結果(システムpage cacheのため大きい):
use pointer dir:/data/
test begin
all file list size:7803
src file list size:7796
 dst_file_list_size:7796
test end,read size:11681.930182M cost:63.431233,speed:184.166847M/s
You have new mail in/var/mail/root
dg35_r710_9sd6t2x:/webservice/server/jiangwenlong/fileio # 
テストコード:
依存ライブラリ:libeio,libapr,boost
     
   #include <apr.h>
#include <apr_lib.h>
#include <apr_general.h>
#include <apr_poll.h>
#include <apr_pools.h>
#include <eio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>

#include <apr_file_io.h>
#include <apr_strings.h>
#include <boost/filesystem.hpp>
#include <vector>

void want_poll();
void done_poll();
void apr_create_poll();
void apr_create_pool();
void apr_create_pipe();
void event_loop();
//TODO:read & write function for eio callback 
int write_cb(eio_req * req);
int read_cb(eio_req * req);
int open_cb(eio_req * req);
int close_cb(eio_req * req);

void read_dir();
void random_read();
void order_read();
void random_write();
void order_write();

static apr_pool_t *p = NULL;
static apr_pollset_t *pollset = NULL;
static int MAX_WATCH_SIZE = 100;
static apr_file_t *readp = NULL;
static apr_file_t *writep = NULL;

static long		  read_size=0;
static long		  write_size=0;

typedef struct _tag_FILE_INFO{
	int         fd;
	std::string file_path;
	int			file_size;
	bool        is_regular_file;
	time_t      last_write_time;
	char		*buf[256];
	int			pos ;
	_tag_FILE_INFO(){
		fd = 0;
		file_size = 0;
		last_write_time = 0;
		pos = 0;
	}
}FILE_INFO;

static char src_path[256] = "../";
static char dst_path[256] = "test_dst_data";
static std::vector<FILE_INFO>src_file_path_stat;
static std::vector<FILE_INFO>src_file_path_list;
static std::vector<std::string>dst_file_path_list;

//TODO:for eio callback want_poll
void want_poll()
{
	char c;
	apr_size_t size=1;
	if(apr_file_write(writep,&c,&size)
			!= APR_SUCCESS){
		printf("write pipe error
"); exit(1); } } //TODO:for eio_callback done_poll void done_poll() { char c; apr_size_t size=1; if(apr_file_read(readp,&c,&size) != APR_SUCCESS){ printf("read pipe error
"); } } //TODO:use apr lib create pipe void apr_create_pipe() { if(apr_file_pipe_create(&readp,&writep,p) != APR_SUCCESS){ abort(); } } //TODO:use apr lib create pollset void apr_create_poll() { if(apr_pollset_create(&pollset,MAX_WATCH_SIZE,p,0) != APR_SUCCESS){ abort(); } } //TODO:clean all what apr need clean void apr_clean_all() { if(apr_file_close(readp) != APR_SUCCESS){ printf("close pipe read fd error
"); } if(apr_file_close(writep) != APR_SUCCESS){ printf("close pipe write fd error
"); } } //TODO:use apr create pool void apr_create_pool() { if(apr_pool_create(&p,NULL) != APR_SUCCESS){ abort(); } } //TODO:for watch void event_loop() { apr_pollfd_t pollfd; pollfd.desc_type = APR_POLL_FILE; pollfd.reqevents = APR_POLLIN; pollfd.desc.f = readp; if(apr_pollset_add(pollset,&pollfd) != APR_SUCCESS){ printf("add fd to pollset error
"); exit(1); } while(eio_nreqs()){ int num=0; const apr_pollfd_t *outfd=NULL; if(apr_pollset_poll(pollset,-1,&num,&outfd) != APR_SUCCESS){ printf("apr_poll error
"); } if(num != 1){ printf("incorrect events
"); }else{ int rc = eio_poll(); if(rc == -1) printf("eio_poll error:%d
",eio_poll()); } } apr_pollset_remove(pollset,&pollfd); } int write_cb(eio_req * req) { int rc = EIO_RESULT(req); if( rc <= 0 ){ printf("write file:%s rc:%d,error msg:%s
",(char*)req->data,rc,strerror(req->errorno)); abort(); } return 0; } int read_cb(eio_req * req) { int rc = EIO_RESULT(req); if ( rc < 0){ printf("read file:%s rc:%d error msg:%s
",(char*)req->data,rc,strerror(req->errorno)); abort(); } FILE_INFO* info = (FILE_INFO*)req->data; //printf("file:%-20s\tread size:%d
",info->file_path.c_str(),rc); read_size+=rc; return 0; } int open_cb(eio_req * req) { int rc = EIO_RESULT(req); FILE_INFO * info = (FILE_INFO*)req->data; if(rc <= 0){ printf("open file :%s ,error msg:%s
",info->file_path.c_str(),strerror(req->errorno)); return 0; abort(); } info->fd = rc; //printf("open file fd:%d
",info->fd); return 0; } int close_cb(eio_req *req) { int rc = EIO_RESULT(req); if( rc != 0){ printf("close file error,error msg:%s
",strerror(req->errorno)); abort(); } return 0; } void read_dir() { boost::filesystem::path spath(src_path); if(!boost::filesystem::is_directory(spath)){ printf("error,src_path not directory
"); abort(); } boost::filesystem::recursive_directory_iterator rcs_iter(spath); boost::filesystem::recursive_directory_iterator end; //boost::filesystem::directory_iterator rcs_iter(spath); //boost::filesystem::directory_iterator end; for(;rcs_iter != end; ++rcs_iter){ FILE_INFO finfo; try{ finfo.is_regular_file = boost::filesystem::is_regular_file(*rcs_iter); finfo.last_write_time = boost::filesystem::last_write_time(*rcs_iter); finfo.file_path = (*rcs_iter).path().string(); finfo.file_size = boost::filesystem::file_size(*rcs_iter); src_file_path_stat.push_back(finfo); //printf("file:%s
",finfo.file_path.c_str()); }catch(...){ } } printf("all file list size:%d
",src_file_path_stat.size()); std::vector<FILE_INFO>::iterator f_iter,f_end; f_iter = src_file_path_stat.begin(); f_end = src_file_path_stat.end(); for(; f_iter != f_end; ++f_iter){ if(f_iter->is_regular_file && f_iter->file_size > 0){ src_file_path_list.push_back(*f_iter); boost::filesystem::path temp_path(f_iter->file_path); dst_file_path_list.push_back(temp_path.filename().string()); //printf("filename:%s
",temp_path.filename().string().c_str()); } } printf("src file list size:%d\t dst_file_list_size:%d
",src_file_path_list.size(),dst_file_path_list.size()); } void random_read() { srand(time(NULL)); bool exit_flag = false; //while(!exit_flag){ for(int i=0; i<src_file_path_list.size(); ++i){ if(src_file_path_list.at(i).fd == 0){ continue; } int temp_size = src_file_path_list.at(i).file_size / 256*1024 ; if(temp_size == 0){ continue; } int read_bytes=rand()%(temp_size>100?100*256*1024:100*1024); int offset =rand()%(1024*1024); offset=(offset+read_bytes)>src_file_path_list.at(i).file_size ? (rand()%100):offset; char *buf = NULL; buf = (char*)apr_palloc(p,read_bytes+1); if(buf == NULL){ printf("use apr poll alloc memory error
"); continue; } //printf("read file:%-20s,file size:%-10d,offset:%-5d,length:%-10d
", //src_file_path_list.at(i).file_path.c_str(), //src_file_path_list.at(i).file_size,offset,read_bytes); src_file_path_list.at(i).buf[src_file_path_list.at(i).pos++] = buf; eio_read(src_file_path_list.at(i).fd,buf,read_bytes,offset,0,read_cb,&src_file_path_list.at(i)); if(src_file_path_list.at(i).pos >= 10){ printf("buf list is full out
"); exit_flag = true; break; } } //} } int main(int argc,char **argv) { apr_initialize(); apr_create_pool(); apr_create_pipe(); apr_create_poll(); if(eio_init(want_poll,done_poll)){ abort(); } if(argc == 2){ printf("use pointer dir:%s
",argv[1]); memset(src_path,0,256); sprintf(src_path,"%s",argv[1]); } printf("test begin
"); read_dir(); for(int i = 0; i < src_file_path_list.size(); ++i){ if(i > 1000)break; eio_open(src_file_path_list.at(i).file_path.c_str(),O_RDONLY,0644,0,open_cb,&src_file_path_list.at(i)); } event_loop(); apr_time_t begin = apr_time_now(); random_read(); event_loop(); apr_time_t end = apr_time_now(); for(int i = 0; i < src_file_path_list.size(); ++i){ if(src_file_path_list.at(i).fd > 0) eio_close(src_file_path_list.at(i).fd,0,close_cb,NULL); } event_loop(); double total_size = read_size*1.0/(1024*1024); double cost_time = (end-begin)/1000000.0; double speed = total_size/cost_time; printf("test end,read size:%lfM cost:%lf,speed:%lfM/s
",read_size*1.0/(1024*1024),(end-begin)/1000000.0,speed); apr_terminate(); return 0; }