C++ 内存中哪一个更快,整数还是字符?文件映射还是块读取?
好的,我以前写过一个(相当未优化的)程序来将图像编码为JPEG,但是,现在我正在处理MPEG-2传输流和其中的H.264编码视频。在我开始编写所有这些之前,我很好奇处理实际文件的最快方法是什么 目前,我正在将.mts文件映射到内存中以处理它,尽管我不确定(例如)将100 MB的文件分块读取到内存中并以这种方式处理是否会更快 这些文件需要大量的位移位等来读取标志,所以我想知道,当我引用一些内存时,一次读取4个字节作为整数还是读取1个字节作为字符会更快。我想我在哪里读到过x86处理器被优化为4字节粒度,但我不确定这是不是真的C++ 内存中哪一个更快,整数还是字符?文件映射还是块读取?,c++,optimization,memory,file,integer,C++,Optimization,Memory,File,Integer,好的,我以前写过一个(相当未优化的)程序来将图像编码为JPEG,但是,现在我正在处理MPEG-2传输流和其中的H.264编码视频。在我开始编写所有这些之前,我很好奇处理实际文件的最快方法是什么 目前,我正在将.mts文件映射到内存中以处理它,尽管我不确定(例如)将100 MB的文件分块读取到内存中并以这种方式处理是否会更快 这些文件需要大量的位移位等来读取标志,所以我想知道,当我引用一些内存时,一次读取4个字节作为整数还是读取1个字节作为字符会更快。我想我在哪里读到过x86处理器被优化为4字节粒
谢谢 如果您要求文件同步可用,则内存映射文件通常是可用的最快操作。(有些异步API允许O/S重新排序,有时速度略有提高,但这听起来对应用程序没有帮助) 映射文件的主要优点是,当O/S仍在从磁盘读取文件时,您可以在内存中处理该文件,并且不必管理自己的锁定/线程化文件读取代码 内存引用方面,在x86上,无论您实际使用的是什么,每次都将读取整行内存。与非字节粒度操作相关的额外时间指的是整数不需要字节对齐的事实。例如,如果没有在4字节边界上对齐,则执行ADD将花费更多的时间,但对于内存拷贝之类的东西,这几乎没有什么区别。如果您使用的是固有的字符数据,那么保持这种方式将比以整数和位移位的形式读取所有内容更快
如果您正在进行h.264或MPEG2编码,那么在任何情况下,瓶颈都可能是CPU时间,而不是磁盘i/o。如果您必须访问整个文件,将其读取到内存并在那里进行处理总是会更快。当然,这也是在浪费内存,而且您必须以某种方式锁定文件,这样您就不会被其他应用程序并发访问,但优化无论如何都是要妥协的。如果您跳过文件的(大)部分,内存映射会更快,因为您根本不需要读取它们 是的,以4字节(甚至8字节)粒度访问内存比按字节访问内存要快。同样,这是一种折衷方案——取决于您以后对数据的处理方式,以及您在处理int中的位方面的熟练程度,总体而言,它可能不会更快 关于优化方面的一切:
关于从内存中读取的最佳大小,我相信您会喜欢阅读有关内存访问性能和缓存效果的内容。这些是连续的位流-基本上每次只消耗一位,而不进行随机访问 您不需要在显式缓冲读取上投入大量精力,在这种情况下:操作系统将为您缓冲读取。我以前写过H.264解析器,时间完全取决于解码和操作,而不是IO 我的建议是使用标准库和解析这些位流 就是这样一个解析器,该网站甚至包括MPEG-2(PS)和各种H.264部件(如M-Coder)的示例。Flavor从类似c++的语言构建本机解析代码;这里引用了MPEG-2 PS规范:
class TargetBackgroundGridDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 7
{
unsigned int(14) horizontal_size;
unsigned int(14) vertical_size;
unsigned int(4) aspect_ratio_information;
}
class VideoWindowDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 8
{
unsigned int(14) horizontal_offset;
unsigned int(14) vertical_offset;
unsigned int(4) window_priority;
}
<> P>内存映射文件要考虑的一个问题是,文件大小大于可用地址范围的文件只能映射文件的一部分。要访问文件的其余部分,需要取消映射第一个零件,并在其位置映射下一个零件 由于您正在解码mpeg流,您可能希望使用双缓冲方法进行异步文件读取。它的工作原理如下:
blocksize = 65536 bytes (or whatever)
currentblock = new byte [blocksize]
nextblock = new byte [blocksize]
read currentblock
while processing
asynchronously read nextblock
parse currentblock
wait for asynchronous read to complete
swap nextblock and currentblock
endwhile
+1,是不是“再保证一次,再保证一次,再优化一次”?