首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将文件映射多线程到缓冲区数组中

将文件映射多线程到缓冲区数组中
EN

Stack Overflow用户
提问于 2013-03-12 16:02:35
回答 1查看 460关注 0票数 0

我正在尝试处理讨厌的大型xml和文本文档:~40 to。我在Windows 7上使用Visual 2012。

我将使用'Xerces‘从xmls抓取页眉/’页脚‘标记。

我想要映射文件的一个区域,比如说..。60-120

将Map拆分为(3 *处理器/核)等份。将每个部分设置为缓冲区,并将缓冲区加载到数组中。

然后,在新线程中使用(#处理器/核)状态时,我将同步计数字符/行/xml周期,同时仔细分析缓冲区数组。当一个缓冲区完成时,该进程将跳转到下一个“可用”缓冲区,完成的缓冲区将从内存中删除。最后,我将把总结果添加到项目日志中。

之后,我将引用日志,将文件按字符计数/大小(或其他选项)拆分到最近的行或循环中,并将页眉和“页脚”标记放到所有的分隔符中。

我这样做是为了通过有多台计算机的网络将大量数据导入到MySQL服务器。

我的问题是,如何使用新线程创建缓冲区数组和文件映射?

我可以用:

win CreateFile

win CreateFileMapping

win MapViewOfFile

使用标准的ifstream操作和char缓冲区,还是应该选择其他的?

进一步澄清:我的想法是,如果我能让硬盘把文件从一个地方和一个方向传输到内存中,我就可以使用机器的全部处理能力来咀嚼单独但平等的缓冲区。

~芬芳:这有点像一个谢泼德试图从一个大垃圾桶里挖出食物,里面有3-6个大桶,只有两只胳膊,供X羊在围栏区域内吃。但它们都以光速移动。

一些想法或建议可能对我在这里的生活有所帮助。任何想法都是最受欢迎的。谢谢。

代码语言:javascript
复制
while(getline(my_file, myStr))
{
   characterCount += myStr.length();

   lineCount++;


   if(my_file.eof()){

      break;

   }
}

这是测试运行时唯一的代码。2小时,30+min。45-50%的总处理器的程序运行它的双核1.6Mhz笔记本与2GB RAM。现在加载的大部分内存是从火狐中打开的~50个选项卡中的600+MB,Visual是60 in,然后是etcs。

重要的是:在测试期间,运行代码的程序(它只是一个窗口和一个对话框)似乎转储了它自己的工作和私有的ram集,降低到了300 didn,并且没有响应测试的长度。我确信,我需要为while语句再做一个线程。但这意味着没有任何文件被读取到缓冲区中。整个运行过程中,CPU都在苦苦挣扎,以跟上硬盘上最微小的努力。

进一步证明CPU瓶颈。通过无线网络将整个文件传输到另一台计算机可能需要20分钟。它包括读取进程和套接字捕获以在另一台计算机上写入进程。

更新

我用这个可爱的小东西,从以前的测试时间到15-20分钟,这与Mats Petersson所说的是一致的。

代码语言:javascript
复制
while (my_file.read( &bufferOne[0], bufferOne.size() ))

{

代码语言:javascript
复制
int cc = my_file.gcount();

for (int i = 0; i < cc; i++)
{

    if (bufferOne[i] == '\n')
        lineCount++;

    characterCount++;

}

currentPercent = characterCount/onePercent;

SendMessage(GetDlgItem(hDlg, IDC_GENPROGRESS), PBM_SETPOS, currentPercent, 0);

}

当然,这是一个单独的循环,它的行为实际上比以前的测试更合适。这个测试比上面用Getline显示的紧循环快了800%。我将此循环的缓冲区设置为20 at。我从:SOF - Fastest Example删除了这段代码

但是.

我想指出的是,当在资源管理器和任务管理器中对进程进行轮询时,它清楚地显示了第一个核心在75%-90%的使用率,第二个流动的25-50% (对于我打开的一些次要的背景信息非常标准),以及硬盘。等它..。50%。大约100%的磁盘时间峰值,但也有一些低点在25%。所有这一切基本上意味着在两个不同的线程之间分割缓冲区处理很有好处。它将使用所有的系统资源,但是..。这就是我想要的。我将在今天晚些时候更新我的工作原型。

专业更新:经过大量学习,终于完成了我的项目。不需要文件地图。我已经成功地构建了一个动态执行的文件流行和字符计数器。好消息是,在5.8GB文件BOOYA!~上,从以前的10-15分钟标记到了~3-4分钟。

EN

回答 1

Stack Overflow用户

发布于 2013-03-12 16:14:25

很简单的回答:是的,你可以使用这些功能。

对于读取数据,它可能是将文件内容映射到内存中最有效的方法,因为它省去了将内存复制到应用程序中的缓冲区,只需将其直接读取到它应该去的地方即可。因此,只要您有足够的可用地址空间--64位计算机当然应该有足够的地址空间,那么没有问题,在32位系统中,它可能更像是一种稀缺的资源--但是对于几百MB的部分来说,这不应该是个大问题。

然而,使用多个线程,我一点也不相信。我有一个公平的想法,阅读一个非常大的文件的一个以上的部分将是反作用。这将增加磁头在磁盘上的移动量,这是传输速率的很大一部分。对于“普通”系统,您可以依靠大约50-100 on /s的传输速率。如果系统有某种raid控制器或类似的,可能是大约两倍-非常奇特的raid控制器可能达到三次。

因此,阅读40 15将花费3-15分钟的时间。

CPU可能不会很忙,运行多个线程很可能会使系统的整体性能恶化。

您可能希望保留一个用于读取的线程和一个用于写入的线程,并且只有在有足够数量的数据时才实际写入数据,以避免磁盘上的读/写头发生不必要的移动。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15366154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档