最近遇到一个问题,要同时读500个文件,每个50kbyte/s一般的硬盘照理说是能读到的25M/s的不过在客户机器上老读不到,是用2~6个thread, fread 来读取的只能最多10M/s 硬盘是一个1200G scsi 硬盘,可以热插拔那种我的程序开2个一共读10M/s ,然后用HD Tune测试,还可以读3M/s平均请问用完成端口能快点不?或者有什么窍门能快点呢?多谢,多谢做过VOD的,能否点拨一二,非常谢谢
调试欢乐多
{
CQuickFileSystemDlg *L=(CQuickFileSystemDlg*)pParam;
L->workFunc(); return 0;
}void CQuickFileSystemDlg::workFunc()
{
int j,i;
void (*f[5])(TCHAR*)={f1,f2,f3,f4,f5};
CString strText,strTmp[2];
buffer=new TCHAR[BUFFER_SIZE];
DWORD Tick;
DWORD NoBufferTotalTime=0,NoBufferEndTime;
DWORD SequenTotalTime=0,SequenEndTime;
DWORD OverlpTotalTime=0,OverlpEndTime;
DWORD NoBufferAverageTime=0;
DWORD SequenAverageTime=0;
DWORD OverlpAverageTime=0; j=0;
showResult("→无文件高速缓存模式开始.");
for(i=0;i<10;i++)
{
if(i==0) strTmp[0]="source.txt";
else strTmp[0].Format("nobuffer%d.txt",i);
strTmp[1].Format("nobuffer%d.txt",i+1);
Tick=GetTickCount();
if(!pFile_NoBuffer(strTmp[0],strTmp[1],f[j])) return;
NoBufferEndTime=GetTickCount();
NoBufferTotalTime+=NoBufferEndTime-Tick;
strText.Format("无缓存 %d-%d: %d ms",i,i+1,NoBufferEndTime-Tick);
if(j++ == 4) j=0;
showResult(strText);
}
showResult("→无文件高速缓存模式结束.",1); j=0;
showResult("→使用文件高速缓存模式开始.");
for(i=0;i<10;i++)
{
if(i==0) strTmp[0]="source.txt";
else strTmp[0].Format("sequen%d.txt",i);
strTmp[1].Format("sequen%d.txt",i+1);
Tick=GetTickCount();
if(!pFile_Sequen(strTmp[0],strTmp[1],f[j])) return;
SequenEndTime=GetTickCount();
SequenTotalTime+=SequenEndTime-Tick;
strText.Format("使用缓存 %d-%d: %d ms",i,i+1,SequenEndTime-Tick);
if(j++ == 4) j=0;
showResult(strText);
}
showResult("→使用文件高速缓存模式结束.",1); j=0;
showResult("→异步传输模式开始.");
for(i=0;i<10;i++)
{
if(i==0) strTmp[0]="source.txt";
else strTmp[0].Format("overlp%d.txt",i);
strTmp[1].Format("overlp%d.txt",i+1);
Tick=GetTickCount();
if(!pFile_Overlp(strTmp[0],strTmp[1],f[j])) return;
OverlpEndTime=GetTickCount();
OverlpTotalTime+=OverlpEndTime-Tick;
strText.Format("异步传输 %d-%d: %d ms",i,i+1,OverlpEndTime-Tick);
if(j++ == 4) j=0;
showResult(strText);
}
showResult("→异步传输模式结束.",1);
delete []buffer; showResult("→三种模式下的平均时间以做对比:");
strText.Format("·无文件高速缓存模式平均用时: %d ms",NoBufferTotalTime/10);
showResult(strText);
strText.Format("·使用文件高速缓存模式平均用时: %d ms",SequenTotalTime/10);
showResult(strText);
strText.Format("·异步传输模式平均用时: %d ms",OverlpTotalTime/10);
showResult(strText);
}void CQuickFileSystemDlg::showResult(CString strText,int nReturn)
{
CString strEdit;
m_ShowResult.GetWindowText(strEdit);
m_ShowResult.SetFocus();
m_ShowResult.SetSel(strEdit.GetLength(),strEdit.GetLength());
//m_ShowResult.SetSel(-1,-1);
m_ShowResult.ReplaceSel(strText+"\n");
for(int i=0;i<nReturn;i++)
{
m_ShowResult.GetWindowText(strEdit);
m_ShowResult.SetFocus();
m_ShowResult.SetSel(strEdit.GetLength(),strEdit.GetLength());
m_ShowResult.ReplaceSel("\n");
}
//UpdateData(TRUE);
}BOOL CQuickFileSystemDlg::pFile_NoBuffer(CString pSource,CString pSink,void (*func)(TCHAR* addr))
{
HANDLE handle_src,handle_dst;
BOOL cycle=TRUE;
DWORD NumberOfBytesRead,NumberOfBytesWrite,index; handle_src=CreateFile(pSource,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL); handle_dst=CreateFile(pSink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NULL); if(handle_src==INVALID_HANDLE_VALUE)
{
showResult("打开源文件“"+pSource+"”错误!终止。");
return FALSE;
}
else if(handle_dst==INVALID_HANDLE_VALUE)
{
showResult("创建目标文件“"+pSink+"”错误!终止。");
return FALSE;
} while(cycle)
{
if(!ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL))
{
showResult("读取文件“"+pSource+"”错误!终止。");
return FALSE;
} if(NumberOfBytesRead<BUFFER_SIZE) cycle=FALSE; for(index=0;index<NumberOfBytesRead;index++) func(&buffer[index]); if(!WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL))
{
showResult("写文件“"+pSink+"”错误!终止。");
return FALSE;
}
} CloseHandle(handle_src);
CloseHandle(handle_dst);
return TRUE;
}BOOL CQuickFileSystemDlg::pFile_Sequen(CString pSource,CString pSink,void (*func)(TCHAR* addr))
{
HANDLE handle_src,handle_dst;
BOOL cycle=TRUE;
DWORD NumberOfBytesRead,NumberOfBytesWrite,index; handle_src=CreateFile(pSource,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
handle_dst=CreateFile(pSink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL); if(handle_src==INVALID_HANDLE_VALUE)
{
showResult("打开源文件“"+pSource+"”错误!终止。");
return FALSE;
}
else if(handle_dst==INVALID_HANDLE_VALUE)
{
showResult("创建目标文件“"+pSink+"”错误!终止。");
return FALSE;
} while(cycle)
{
if(!ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL))
{
showResult("读取文件“"+pSource+"”错误!终止。");
return FALSE;
} if(NumberOfBytesRead<BUFFER_SIZE) cycle=FALSE; for(index=0;index<NumberOfBytesRead;index++) func(&buffer[index]); if(!WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL))
{
showResult("写文件“"+pSink+"”错误!终止。");
return FALSE;
}
} CloseHandle(handle_src);
CloseHandle(handle_dst);
return TRUE;
}BOOL CQuickFileSystemDlg::pFile_Overlp(CString pSource,CString pSink,void (*func)(TCHAR* addr))
{
HANDLE handle_src,handle_dst;
BOOL cycle=TRUE;
DWORD NumberOfBytesRead,NumberOfBytesWrite,index,dwError;
OVERLAPPED overlapped; handle_src=CreateFile(pSource,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED,NULL);
handle_dst=CreateFile(pSink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NULL); if(handle_src==INVALID_HANDLE_VALUE)
{
showResult("打开源文件“"+pSource+"”错误!终止。");
return FALSE;
}
else if(handle_dst==INVALID_HANDLE_VALUE)
{
showResult("创建目标文件“"+pSink+"”错误!终止。");
return FALSE;
} overlapped.hEvent=NULL;
overlapped.Offset=-BUFFER_SIZE;
overlapped.OffsetHigh=0; while(cycle)
{
overlapped.Offset=overlapped.Offset+BUFFER_SIZE; if(!ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,&overlapped))
{
switch(dwError=GetLastError())
{
case ERROR_HANDLE_EOF:
cycle=FALSE;
break;
case ERROR_IO_PENDING:
if(!GetOverlappedResult(handle_src,&overlapped,&NumberOfBytesRead,TRUE))
{
showResult("异步读文件“"+pSource+"”错误!终止。");
return FALSE;
}
break;
default:
break;
}
} if(NumberOfBytesRead<BUFFER_SIZE) cycle=FALSE; for(index=0;index<NumberOfBytesRead;index++) func(&buffer[index]); if(!WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL))
{
showResult("写文件“"+pSink+"”错误!终止。");
return FALSE;
}
} CloseHandle(handle_src);
CloseHandle(handle_dst);
return TRUE;
}void CQuickFileSystemDlg::OnStart()
{
CWinThread *m_pThread;
m_pThread=AfxBeginThread(ThreadProc,this);
ASSERT(m_pThread);
m_pThread->m_bAutoDelete=TRUE;
m_pThread->ResumeThread();
}
不管直接用ReadFile还是文件映射,在内部都是通过ReadFile来实现,只不过这此细节被操作系统隐藏起来,目的就是为了操作方便。
SCSI硬盘本身的优势就是并发读写,而不是连续读写
按指定的速度执行
你需要在线程里执行速度控制,计算开始读的时间和结束时间,不到1秒,就SLEEP掉应该使用多线程读,因为SCSI和IDE或者SATA硬盘不一样,SCSI硬盘你采用1-2个线程几个顺序读的话,等于没利用它的并发性能,建议开到4-8个并发读另外一个没看清楚,为什么采用 NO BUFFER模式? 你是设置无缓冲吗? 那会导致性能直线下降
我是直接用fopen读的,无缓冲是另外一个人给的代码