请问如何快速的同时读500个文件,每个50kbyte/s,非常谢谢

Oversense 2007-07-13 11:34:48
最近遇到一个问题,要同时读500个文件,每个50kbyte/s

一般的硬盘照理说是能读到的25M/s的

不过在客户机器上老读不到,是用2~6个thread, fread 来读取的

只能最多10M/s

硬盘是一个1200G scsi 硬盘,可以热插拔那种

我的程序开2个一共读10M/s ,然后用HD Tune测试,还可以读3M/s平均

请问用完成端口能快点不?或者有什么窍门能快点呢?多谢,多谢

做过VOD的,能否点拨一二,非常谢谢
...全文
366 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Oversense 2007-07-15
  • 打赏
  • 举报
回复
to danscort2000(danscort.yu)
我是直接用fopen读的,无缓冲是另外一个人给的代码
danscort2000 2007-07-15
  • 打赏
  • 举报
回复
这跟内存映射有什么关系?
SCSI硬盘本身的优势就是并发读写,而不是连续读写
按指定的速度执行
你需要在线程里执行速度控制,计算开始读的时间和结束时间,不到1秒,就SLEEP掉

应该使用多线程读,因为SCSI和IDE或者SATA硬盘不一样,SCSI硬盘你采用1-2个线程几个顺序读的话,等于没利用它的并发性能,建议开到4-8个并发读

另外一个没看清楚,为什么采用 NO BUFFER模式? 你是设置无缓冲吗? 那会导致性能直线下降

DentistryDoctor 2007-07-15
  • 打赏
  • 举报
回复
磁盘IO多线程反而会降低性能的。
CathySun118 2007-07-15
  • 打赏
  • 举报
回复
不要迷信内存映射
不管直接用ReadFile还是文件映射,在内部都是通过ReadFile来实现,只不过这此细节被操作系统隐藏起来,目的就是为了操作方便。
菜牛 2007-07-14
  • 打赏
  • 举报
回复
估计也就这样子了,不太现实。
yunyu97 2007-07-14
  • 打赏
  • 举报
回复
使用内存映射,可以快很多,还有就是与你读文件的块的大小有关。
秋忆 2007-07-14
  • 打赏
  • 举报
回复
使用缓存,快速文件系统复制,然后多线程。可以参考以下程序:

UINT ThreadProc(LPVOID pParam)
{
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();
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧