google
级别: 测试新手
精华:
0
发帖: 1
基地声望: 2 点
基地币: 6425 Bug
基地贡献: 0 点
好评度: 0 点
在线时间:0(小时)
注册时间:2006-06-30
最后登录:2006-06-30
|
『转贴』大家好 看看这个东东 很有意思哦
图片:
图片:
转自:http://blog.csdn.net/johnlya 大家好 CSDN上的有一个好东东 呵呵 挺有意思 大家可以看看哦
本文主要测试的是eXtremeDB的事务和BerkeleyDB的自动加锁的在多线程调度下的成功率以及所花费的时间的差别。(操作数为10万次) 1、eXtremeDB的测试源程序: #include "McoDBInfo.h" #include "include\mco.h" #include "platform\platform.h" #include <stdio.h> #include <stdlib.h> #include <string.h>
#define DBSIZE (1024*1024*100) #define PAGESIZE 64 #define NOBJECTS 5 #define NTHREADS 6 #define NEXECUTE 100000 const int MAP_ADDRESS = 0x20000000; const char dbN[] = "McoDBInfo"; mco_db_h db =0; void* start_mem; HANDLE hThread = 0,hDeleThread = 0,hUpdateThread[NTHREADS] = {NULL},hCheckThread = 0; volatile BOOL threadsign = FALSE,UpdateSign = FALSE,DeleteSign = FALSE,CheckSign = FALSE; unsigned long m_iRecord[3] ={0},m_couter =0,m_iSuccess[3] = {0}; DWORD m_start = 0,m_end = 0; CRITICAL_SECTION m_Critical; LARGE_INTEGER frequent; LARGE_INTEGER startcount,endcount; void insertData(mco_db_h db) { MCO_RET rc; TimeStamp timec; mco_trans_h t; double m_value = 0.0; rc = mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); m_couter ++; EnterCriticalSection(&m_Critical); m_iRecord[0]++; LeaveCriticalSection(&m_Critical); TimeStamp_new(t,&timec); m_value = 1.0*m_couter; TimeStamp_m_iID_put(&timec,m_value); rc = mco_trans_commit(t); if(rc == MCO_S_OK) { // printf("%d\n",m_iRecord);fflush( stdout ); EnterCriticalSection(&m_Critical); m_iSuccess[0]++; LeaveCriticalSection(&m_Critical); } else { printf("Insert Error!!!\n"); } } void DeletData(mco_db_h db) { MCO_RET rc; TimeStamp timec; mco_trans_h t; mco_cursor_t timecsr; mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); EnterCriticalSection(&m_Critical); m_iRecord[1]++; LeaveCriticalSection(&m_Critical); TimeStamp_list_cursor(t,&timecsr); rc =mco_cursor_first(t,&timecsr); rc =TimeStamp_from_cursor(t,&timecsr,&timec); rc = TimeStamp_delete(&timec); rc = mco_trans_commit(t); if(rc == MCO_S_OK) { // printf("%d\n",m_iRecord);fflush( stdout ); EnterCriticalSection(&m_Critical); m_iSuccess[1]++; LeaveCriticalSection(&m_Critical); } else { printf("delete Error!!!\n"); } } void UpdateData(mco_db_h db) { MCO_RET rc; TimeStamp timec; mco_trans_h t; mco_cursor_t timecsr; mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); EnterCriticalSection(&m_Critical); m_iRecord[2]++; LeaveCriticalSection(&m_Critical); TimeStamp_list_cursor(t,&timecsr); rc =mco_cursor_last(t,&timecsr); rc =TimeStamp_from_cursor(t,&timecsr,&timec); TimeStamp_m_iID_put(&timec,m_couter); rc = mco_trans_commit(t); if(rc == MCO_S_OK) { // printf("%d\n",m_iRecord);fflush( stdout ); EnterCriticalSection(&m_Critical); m_iSuccess[2]++; LeaveCriticalSection(&m_Critical); } else { printf("Update Error!!!\n"); } } DWORD WINAPI InsertThread( LPVOID lpParam ) { while(!threadsign) { // HANDLE m_hMutex; // 创建互斥量 // m_hMutex = CreateMutex(NULL, FALSE, "DELETDB"); // 检查错误代码 // if (GetLastError() == ERROR_ALREADY_EXISTS) // { // CloseHandle(m_hMutex); // m_hMutex = NULL; // continue; // } insertData(db); // CloseHandle(m_hMutex); // m_hMutex = NULL; // Sleep(25); } return 0; } //删除数据 DWORD WINAPI DeleteThread( LPVOID lpParam ) { while(!DeleteSign) { // HANDLE m_hMutex; // 创建互斥量 // m_hMutex = CreateMutex(NULL, FALSE, "DELETDB"); // 检查错误代码 // if (GetLastError() == ERROR_ALREADY_EXISTS) // { // CloseHandle(m_hMutex); // m_hMutex = NULL; // continue; // } DeletData(db); // CloseHandle(m_hMutex); // m_hMutex = NULL; // Sleep(25); } return 0; } //更新数据 DWORD WINAPI UpdateThread( LPVOID lpParam ) { while(!UpdateSign) { // HANDLE m_hMutex; // 创建互斥量 // m_hMutex = CreateMutex(NULL, FALSE, "DELETDB"); // 检查错误代码 // if (GetLastError() == ERROR_ALREADY_EXISTS) // { // CloseHandle(m_hMutex); // m_hMutex = NULL; // continue; // } UpdateData(db); // CloseHandle(m_hMutex); // m_hMutex = NULL; // Sleep(25); } return 0; } //监测数据 DWORD WINAPI CheckThread( LPVOID lpParam ) { mco_runtime_info_t *m_info = (mco_runtime_info_t *)lpParam; while(!CheckSign) { if ((m_iRecord[0]+m_iRecord[1]+m_iRecord[2])>NEXECUTE) { threadsign = TRUE; UpdateSign = TRUE; DeleteSign = TRUE; unsigned long elaspe; QueryPerformanceCounter(&endcount); elaspe = ((double)(endcount.QuadPart - startcount.QuadPart) /(double)frequent.QuadPart*1000*1000); Sleep(10); //等待事务做完后关闭线程 printf("Total InsertTrans is %ld\n",m_iRecord[0]); printf("Successful InsertTrans is %ld\n",m_iSuccess[0]); printf("Total DeletTrans is %ld\n",m_iRecord[1]); printf("Successful DeletTrans is %ld\n",m_iSuccess[1]); printf("Total UpdateTrans is %ld\n",m_iRecord[2]); printf("Successful UpdateTrans is %ld\n",m_iSuccess[2]); printf("Total Trans is %ld\n",m_iRecord[0]+m_iRecord[1]+m_iRecord[2]); printf("Successful Trans is %ld\n",m_iSuccess[0]+m_iSuccess[1]+m_iSuccess[2]); int lostrate = 0; lostrate = (double)(m_iRecord[0]+m_iRecord[1]+m_iRecord[2] -(m_iSuccess[0]+m_iSuccess[1]+m_iSuccess[2])) /(double)(m_iRecord[0]+m_iRecord[1]+m_iRecord[2])*100; printf("Lost data rate is (%):%d\n",lostrate); printf("Total Time is %ld millisecond\n",elaspe/1000); printf("Time every Trans is %ld microsecond\n",elaspe/(m_iRecord[0]+m_iRecord[1]+m_iRecord[2])); printf("Time every Success is %ld micorosecond\n",elaspe/(m_iSuccess[0]+m_iSuccess[1]+m_iSuccess[2])); if (hThread) CloseHandle(hThread); for (int i=0;i<NTHREADS;i++) { if (hUpdateThread) CloseHandle(hUpdateThread); } if (hDeleThread) CloseHandle(hDeleThread); DeleteCriticalSection(&m_Critical); mco_db_disconnect(db); mco_db_close(dbN); mco_runtime_stop(); if(!m_info->mco_shm_supported) free(start_mem); CheckSign = TRUE; } } ExitThread(10); return 0; }int file_reader(void *stream_handle /* FILE * */, /* OUT */ void * to, unsigned max_nbytes) { FILE *f = (FILE*)stream_handle; int nbs = fread(to,1,max_nbytes,f); return nbs; } int main(int argc, char* argv[]) { MCO_RET rc; DWORD dwThreadID,dwThreadID2,dwThreadID3,dwThreadID4; unsigned long eslapetime=0; mco_runtime_info_t info; if (!QueryPerformanceFrequency(&frequent)) { printf("not supported!\n"); } mco_get_runtime_info( &info); if ( info.mco_shm_supported ) { start_mem = (char*)MAP_ADDRESS; } else { start_mem = (char*)malloc(DBSIZE); if (!start_mem) { printf("Couldn't allocated memory\n"); exit (1); } }; /* start db engine */ if ( mco_runtime_start() != MCO_S_OK) { printf( "\nUnable to start database engine\n" ); if ( !info.mco_shm_supported ) free( start_mem ); exit(-1); }; mco_db_kill(dbN); rc = mco_db_open(dbN, McoDBInfo_get_dictionary(),start_mem,DBSIZE,(uint2)PAGESIZE); if(rc){ printf("\ncreate db err, %d\n", rc); if(!info.mco_shm_supported) free(start_mem); exit(1); } rc = mco_db_connect(dbN, &db); if(rc){ printf("database connect err\n"); exit(-1); } // InitializeCriticalSection(&m_Critical); QueryPerformanceCounter(&startcount); hCheckThread = CreateThread( NULL, 0, CheckThread, (LPVOID)&info, 0, &dwThreadID4 ); hThread = CreateThread( NULL, 0, InsertThread, (LPVOID)NULL, 0, &dwThreadID ); for (int i=0;i<NTHREADS;i++) { hUpdateThread = CreateThread( NULL, 0, UpdateThread, (LPVOID)NULL, 0, &dwThreadID2 ); } hDeleThread = CreateThread( NULL, 0, DeleteThread, (LPVOID)NULL, 0, &dwThreadID3 ); WaitForSingleObject(hCheckThread,INFINITE); if (hCheckThread) CloseHandle(hCheckThread); return 0; } 其数据库为: #define int1 signed<1> #define int2 signed<2> #define int4 signed<4> #define int8 signed<8> #define uint8 unsigned<8> #define uint4 unsigned<4> #define uint2 unsigned<2> #define uint1 unsigned<1>
declare database McoDBInfo; class TimeStamp { double m_iID; //时间戳ID list; // }; 2、BerkeleyDB的测试源程序为: // DbPerformance.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <sys/types.h> #include "afxwin.h" #include <iostream> #include <iomanip> #include <errno.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include "db_cxx.h" using namespace std; #define LOOP 100000 #define THREAD_COUNT 8 #define NTHREADS 6 #define NEXECUTE 100000 HANDLE hThread = 0,hDeleThread = 0,hUpdateThread[NTHREADS] = {NULL},hCheckThread = 0; volatile BOOL threadsign = FALSE,UpdateSign = FALSE,DeleteSign = FALSE,CheckSign = FALSE; const u_int32_t pagesize =1024; const u_int bulkbufsize = 4 * 1024 * 1024; const u_int logbufsize = 8 * 1024 * 1024; const u_int cachesize = 100 * 1024 * 1024; const u_int datasize = 32; const u_int keysize = 8;
class CDbController{ public: CDbController(char* dbName); ~CDbController(); int WriteMessage(); int UpdateMessage(); int DeleteMessage(); int writeMessage(int number); int readMessage(int number); int printAllRc(); void StartThread(); void WaitForThread(); private: Db * myDb; DbEnv * myEnv; unsigned long m_iRecord[3]; unsigned long m_iSuccess[3]; LARGE_INTEGER frequent; LARGE_INTEGER startcount,endcount; CRITICAL_SECTION m_Critical; static DWORD WINAPI InsertThread(LPVOID lpParam); static DWORD WINAPI DeleteThread(LPVOID lpParam); static DWORD WINAPI UpdateThread(LPVOID lpParam); static DWORD WINAPI CheckThread( LPVOID lpParam ); } ; DWORD WINAPI CDbController::InsertThread( LPVOID lpParam ) { CDbController *pControl = (CDbController*)lpParam; while(!threadsign) { pControl->WriteMessage(); } return 0; } //删除数据 DWORD WINAPI CDbController::DeleteThread( LPVOID lpParam ) { CDbController *pControl = (CDbController*)lpParam; while(!DeleteSign) { pControl->DeleteMessage(); } return 0; } //更新数据 DWORD WINAPI CDbController::UpdateThread( LPVOID lpParam ) { CDbController *pControl = (CDbController*)lpParam; while(!UpdateSign) { pControl->UpdateMessage(); } return 0; } //监测数据 DWORD WINAPI CDbController::CheckThread( LPVOID lpParam ) { CDbController *pControl = (CDbController*)lpParam; while(!CheckSign) { if ((pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2])>NEXECUTE) { threadsign = TRUE; UpdateSign = TRUE; DeleteSign = TRUE; unsigned long elaspe; QueryPerformanceCounter(&pControl->endcount); elaspe = ((double)(pControl->endcount.QuadPart - pControl->startcount.QuadPart) /(double)pControl->frequent.QuadPart*1000*1000); Sleep(10); //等待事务做完后关闭线程 printf("Total InsertTrans is %ld\n",pControl->m_iRecord[0]); printf("Successful InsertTrans is %ld\n",pControl->m_iSuccess[0]); printf("Total DeletTrans is %ld\n",pControl->m_iRecord[1]); printf("Successful DeletTrans is %ld\n",pControl->m_iSuccess[1]); printf("Total UpdateTrans is %ld\n",pControl->m_iRecord[2]); printf("Successful UpdateTrans is %ld\n",pControl->m_iSuccess[2]); printf("Total Trans is %ld\n",pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2]); printf("Successful Trans is %ld\n",pControl->m_iSuccess[0]+pControl->m_iSuccess[1]+pControl->m_iSuccess[2]); int lostrate = 0; lostrate = (double)(pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2] -(pControl->m_iSuccess[0]+pControl->m_iSuccess[1]+pControl->m_iSuccess[2])) /(double)(pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2])*100; printf("Lost data rate is (%):%d\n",lostrate); printf("Total Time is %ld millisecond\n",elaspe/1000); printf("Time every Trans is %ld microsecond\n",elaspe/(pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2])); printf("Time every Success is %ld micorosecond\n",elaspe/(pControl->m_iSuccess[0]+pControl->m_iSuccess[1]+pControl->m_iSuccess[2])); if (hThread) CloseHandle(hThread); for (int i=0;i<NTHREADS;i++) { if (hUpdateThread) CloseHandle(hUpdateThread); } if (hDeleThread) CloseHandle(hDeleThread); DeleteCriticalSection(&pControl->m_Critical); CheckSign = TRUE; } } ExitThread(10); return 0; } void CDbController::StartThread() { DWORD dwThreadID1,dwThreadID2,dwThreadID3,dwThreadID4; InitializeCriticalSection(&m_Critical); if (!QueryPerformanceFrequency(&frequent)) { printf("not supported!\n"); } QueryPerformanceCounter(&startcount); hCheckThread = CreateThread( NULL, 0, CheckThread, (LPVOID)this, 0, &dwThreadID4 ); hThread = CreateThread( NULL, 0, InsertThread, (LPVOID)this, 0, &dwThreadID1 ); for (int i=0;i<NTHREADS;i++) { hUpdateThread = CreateThread( NULL, 0, UpdateThread, (LPVOID)this, 0, &dwThreadID2 ); } hDeleThread = CreateThread( NULL, 0, DeleteThread, (LPVOID)this, 0, &dwThreadID3 ); } int CDbController:: readMessage(int number){ char keychar[keysize]; char datachar[datasize]; Dbt key(keychar,keysize); key.set_ulen(keysize); key.set_flags(DB_DBT_USERMEM); Dbt data(datachar,datasize);; data.set_ulen(datasize); data.set_flags(DB_DBT_USERMEM); for(int i=0;i<number;i++){ sprintf(keychar,"%4d",i); int ret=myDb->get(0,&key,&data,0); } return 0; } CDbController::printAllRc(){ Dbc *dbcp; myDb->cursor(NULL, &dbcp, 0); // Walk through the table, printing the key/data pairs. Dbt key; Dbt data; while (dbcp->get(&key, &data, DB_NEXT) == 0) { int *key_string = (int *)key.get_data(); int *data_string = (int *)data.get_data(); printf("%d:%d\n",*key_string,*data_string); //cout << &key_string << " : " << &data_string << "\n"; } dbcp->close(); return 0; } CDbController::CDbController(char* dbName){ u_int32_t env_flags= DB_CREATE |DB_INIT_MPOOL |DB_INIT_LOCK |DB_LOCKDOWN |DB_THREAD // |DB_SYSTEM_MEM; |DB_PRIVATE; u_int32_t db_flags=DB_CREATE; std::string envHome("test"); for (int i=0;i<3;i++) { m_iRecord =0; m_iSuccess =0; } myEnv=new DbEnv(0); myEnv->set_cachesize(0,cachesize,0); myEnv->set_flags(DB_LOG_INMEMORY, 1); // Specify the size of the in-memory log buffer. myEnv->set_lg_bsize(100 * 1024 * 1024); try{ myEnv->open(envHome.c_str(),env_flags,0666); myDb=new Db(myEnv,0); myDb->set_error_stream(&cerr); myDb->set_errpfx("Performance"); myDb->set_pagesize(pagesize); /* Page size: 1K. */ // myDb->set_cachesize(0, cachesize, 0); myDb->open(NULL, NULL, NULL, DB_BTREE, //DB_HASH, db_flags, 0666); }catch(DbException &e){ std::cerr<<"Error opening environment"<<std::endl; std::cerr<<e.what()<<std::endl; exit(-1); }catch(std::exception &e){ std::cerr<<e.what()<<std::endl; exit(-1); } } void CDbController::WaitForThread() { WaitForSingleObject(hCheckThread,INFINITE); } CDbController::~CDbController(){ myDb->close(0); myEnv->close(0); } int CDbController:: WriteMessage(){ char keychar[keysize], datachar[datasize]; memset(keychar,'1',keysize); memset(datachar,'0',datasize); EnterCriticalSection(&m_Critical); m_iRecord[0]++; LeaveCriticalSection(&m_Critical); Dbt key(keychar,keysize); Dbt data(datachar,datasize); sprintf(keychar,"%4d",m_iRecord[0]); int ret = myDb->put(0, &key, &data,0); if (ret==0) { EnterCriticalSection(&m_Critical); m_iSuccess[0]++; LeaveCriticalSection(&m_Critical); } return 0; } int CDbController:: UpdateMessage(){ Dbc *dbcp; myDb->cursor(NULL, &dbcp, 0); char keychar[keysize], datachar[datasize]; memset(keychar,'1',keysize); memset(datachar,'0',datasize); EnterCriticalSection(&m_Critical); m_iRecord[2]++; LeaveCriticalSection(&m_Critical); Dbt key(keychar,keysize); Dbt data(datachar,datasize); sprintf(keychar,"%4d",m_iRecord[2]); int ret = dbcp->put(&key, &data,DB_KEYFIRST); if (ret==0) { EnterCriticalSection(&m_Critical); m_iSuccess[2]++; LeaveCriticalSection(&m_Critical); } dbcp->close(); return 0; } int CDbController:: DeleteMessage(){ Dbc *dbcp; int ret = 0; myDb->cursor(NULL, &dbcp, 0); m_iRecord[1]++; char keychar[keysize], datachar[datasize]; memset(keychar,'1',keysize); memset(datachar,'0',datasize); EnterCriticalSection(&m_Critical); m_iRecord[2]++; LeaveCriticalSection(&m_Critical); Dbt key(keychar,keysize); Dbt data(datachar,datasize); sprintf(keychar,"%4d",m_iRecord[1]); ret = dbcp->get(&key, &data,DB_SET); ret= dbcp->del(0); if (ret==0) { EnterCriticalSection(&m_Critical); m_iSuccess[1]++; LeaveCriticalSection(&m_Critical); } dbcp->close(); return 0; } int CDbController:: writeMessage(int number){ for (int i=0;i<number;i++) { char keychar[keysize], datachar[datasize]; memset(keychar,'1',keysize); memset(datachar,'0',datasize); Dbt key(keychar,keysize); Dbt data(datachar,datasize); sprintf(keychar,"%4d",i); int ret = myDb->put(0, &key, &data,0); } return 0; } int main(int argc, char* argv[]) { LARGE_INTEGER frequent; LARGE_INTEGER startcount,endcount; unsigned long elapsetime =0; // Sleep(2000); if (!QueryPerformanceFrequency(&frequent)) { printf("not supported!\n"); } CDbController controller("abcd"); printf("\n start test performance.\n"); printf("key size= %d byte , data size = %d byte, record number= %d\n",keysize,datasize,LOOP); printf("lock initialized.\n"); //计时开始 QueryPerformanceCounter(&startcount); controller.writeMessage(LOOP); QueryPerformanceCounter(&endcount); elapsetime = (double)(endcount.QuadPart - startcount.QuadPart)/(double)frequent.QuadPart*1000*1000; //打印单线程写耗时 printf("single thread writing, time cost (mm):%ld\n",elapsetime); //计时开始 QueryPerformanceCounter(&startcount); controller.writeMessage(LOOP); QueryPerformanceCounter(&endcount); elapsetime = (double)(endcount.QuadPart - startcount.QuadPart)/(double)frequent.QuadPart*1000*1000; //打印单线程更新耗时 printf("single thread writing, time cost (mm):%ld\n",elapsetime); //计时开始 QueryPerformanceCounter(&startcount); controller.readMessage(LOOP); QueryPerformanceCounter(&endcount); elapsetime = (double)(endcount.QuadPart - startcount.QuadPart)/(double)frequent.QuadPart*1000*1000; //打印单线程更新耗时 printf("single thread reading, time cost (mm):%ld\n",elapsetime); //多线程调度 CDbController controllere("abcde"); controllere.StartThread(); printf("start multiple thread writing and reading.\n"); controllere.WaitForThread(); return 0; } 3、测试结果如下:如图 eXtremeDB: BerkeleyDB:
|
|
|
|
[楼 主]
|
Posted: 2006-06-30 16:23 |
| |