- 浏览: 479553 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
alvin198761:
renzhengzhi 写道我参与过12306余票查询系统的开 ...
别给12306 辩解了 -
renzhengzhi:
我参与过12306余票查询系统的开发,用户请求被前面3层缓存拦 ...
别给12306 辩解了 -
renzhengzhi:
写的很好。
JAVA线程dump的分析 -
liyonghui160com:
说好的附件呢
分布式服务框架 Zookeeper -- 管理分布式环境中的数据 -
ghpaas:
orbeon作为xforms标准的实现,不论其设计器还是运行时 ...
XForms 1.1 中文翻译—第1章 关于XForms标准
我的 前一专栏专注于 16-MB 的内存块,这次我将讨论大小范围在 4 字节到 64 MB 之间的内存块。先前,我检验了各种执行内存传送的方法并确定使用系统提供的 在此处描述的测试中,我运行了几次传送以确保数据是可再生的。我的测试仅在内存为 576 MB 的 ThinkPad 600X (650 MHz) 上运行。没有在其它的双重引导系统上运行过。 我鼓励您在双重引导机器上运行这些测试并报告测试结果。另外,我还鼓励您对程序中的编程方法提出批评和提高性能的建议。本文中,我们的目的是演示最好的编程实践,而不是为证明一个系统比另一个好。 我将使用与上个月几乎相同的程序。仍然使用一个开销小的、简单的源代码管理系统,我将程序重命名为 memxfer5c.cpp。 我所做的更改考虑到了小于 32 个字节的内存块。由于部分循环展开是通过 现在,让我们检查一下块大小和编程技术。我们的测试运行的测试脚本是 test2c.sh。它主要由一长列带有不同块大小和循环计数的 memxfer5c 命令行组成。 Memxfer5c.cpp 的用法信息几乎相同: 测试脚本文件中一个典型的命令行如下所示: 这条命令的意思是按用逗号隔开的列表格式( Memxfer5c.cpp 使用以下命令进行编译: (注意:本系列的 介绍专栏中有对 memxfer5c.cpp 使用的支持例程的描述。) 既然 memxfer5c.cpp 程序可用,而且与上个月的程序几乎没什么差别,所以就不再提供程序清单。我将显示测试运行的图形化结果。使用以下命令运行这个测试: 参数 我们在配备 576 MB 内存和 12-GB 硬盘的 ThinkPad 600X Model 2645-9FU 上运行此脚本。600X 是一台 648 MHz 的 Pentium III 机器。(我的 前一专栏展示了如何在 Windows 和 Linux 下查找处理器型号和以 MHz 为单位的速率。) 测试过的操作系统有: 由于 Linux 内核存在于 Red Hat 7.0 环境中,所以我们使用包含在 Red Hat 7.0 分发版(版本 2.96)中的 gcc。在 Windows 2000 上,我们使用 Visual Studio 6.0 中的 Microsoft C++(版本 12.00.8168)。 运行的一次典型输出 ― 展开各栏后 ― 如下所示: 只有信息中的第 1、第 2、和最后一栏在绘图时被用到。另外两栏被用于验证最后一栏的正确性。例如,从上面的“memcpy”行,我们可以看到: 我使用的是舍位过的数字,可以验证数字 45.792 的正确性,精确到四位有效数字。对于绘图工作,这已经足够了。 看一下数据。前 3 个图(用 Microsoft Excel 制作的)分别代表了每种操作系统上的运行,并显示了这些系统间非常相似的表现。 我还为每个方法绘了一张图,用来显示不同的操作系统: 这些图有一些古怪的地方。首先,在 Linux 上使用 如您所见,代码是同样的。我将 memxfer5c.cpp 源文件复制到 x.cpp,并开始忙于一些琐事。我首先做的是验证正确的方法确实被执行了。然后,我尝试切换方法 3 和方法 4 的顺序,结果是 第 2 点神秘之处是与 Windows 比较时 Linux 在 另外让人觉得好奇的一点就是 Linux 和 Windows 的 memcpy 图中的“锯齿状图形”。当使用的块大小在 4K 到 32K 之间时,Linux 图中就会出现这种“锯齿状图形”。这里是这个区域(锯齿状图形)的放大后的图像,没有使用块大小轴上的记录刻度。 这种表现看起来象是高速缓存级别之间的差频。系统设计者可能不得不解释为什么 Linux 会这样。 读者 Matteo Ianeselli 指出了 gcc 编译器的“-funroll-loops”选项。因为我们输入限制循环次数的变量,所以我不清楚编译器如何展开这些循环中的一个循环。根据我在命令行输入的值,编译器可能已经把循环过分展开。我使用“-funroll-loops”选项在 ThinkPad 770X 上运行一个快速测试。结果如下所示: 我先前已经看过 Microsoft C++ 编译器上的各种选项以查看是否有比“-O2”更好的选项。在我的测试中,我没有发现。我又放弃了继续搜索。但是,如果我们的读者用他/她最喜欢的 cl.exe 上的优化参数编译 memxfer5c.cpp,“并且”使性能得到了提高,请通过 讨论论坛告诉我们。当众多人参与时,搜索 cl.exe 的参数空间的效率就会更高。 这次好象我提出的问题比答案还多。除上面提出的奇怪现象外,我的结果看起来都是在预料之中的。 先前,我慎重地下了结论:在 Linux 和 Windows 下使用 memcpy() 是一个好主意。这个月的测量肯定了这个结论。Memcpy() 产生的结果比 Windows 和 Linux 上任何其它的方法产生的结果都要好。将 Windows 与 Linux 相比较,Windows 在使用 4 字节指针传送内存和传送小于 200 KB 内存时速度更快。传送的内存小于 10 KB 时,局部展开的 Edward Bradford 博士现在为 IBM Software Group 管理 Microsoft Premier Support,并且每周memcpy()
例程是一个很不错的主意(至少在学会其它更好的方法之前,我会一直这样认为)。"double *"
传送进行,所以上个月的程序只允许传送大于或等于 32 个字节。Memxfer5c.cpp 只是仅仅不用 "double *"
方法传送小于 32 字节的内存块。另外,还纠正了用法信息中的一个错误。
memxfer5c 用法信息
Usage:memxfer5c.exe [-f] [-w] [-s] [-p] [-csv] size cnt [method]
-f flag says to malloc and free of the "cnt" times.
-w = set process min and max working set size to "size"
-s = silent; only print averages
-p = prep; "freshen" cache before; -w disables
-csv = print output in CSV format
methods:
0: "memcpy (default)"
1: "char *"
2: "short *"
3: "int *"
4: "long *"
5: "__int64 *"
6: "double *"
memxfer5c -csv -s -p 4 64m 0 1 2 3 4 5 6
"-csv"
)输出数据,汇总信息( "-s"
),“准备”高速缓存( "-p"
),使用 4 字节传送,传送 6400 万次,并为用法信息中列出的每种方法执行这种测试。
gcc -O2 memxfer5c.cpp -o memxfer5c
或
cl -O2 memxfer5c.cpp -o memxfer5c.exe
bash test2c.sh a
a
是一个讨厌的小东西,它强迫我考虑这个测试做什么工作。如果脚本不带参数运行,它只在打印一条用法信息后便退出。任何参数都会起作用。
memxfer5c.exe -s -p -csv 4 67108864 Win2k
"memcpy", 4,268435456, 5.862, 45.789
"char *", 4,268435456, 3.243, 82.771
"short *",4,268435456, 3.139, 85.507
"int *", 4,268435456, 2.721, 98.667
"long *", 4,268435456, 2.720, 98.672
"memcpy", 4,268435456, 5.862, 45.795
"memcpy", 4,268435456, 5.858, 45.828
45.792 = 268435456/(5.862*1E6)
图 1. Linux 2.2.16-22
图 2. Linux 2.4.4
图 3. Win2k
图 4. Linux 和 Win2k 中的 Memcpy
图 5. Linux 和 Win2k 中的 "Char"
图 6. Linux 和 Win2k 中的 "Short"
图 7. Linux 和 Win2k 中的 "Int"
图 8. Linux 和 Win2k 中的 "Long"
图 9. Linux 和 Win2k 中的 "_int64"
图 10. Linux 和 Win2k 中的 "Double"
"long *"
好象比使用 "int *"
更好。既然 int
和 long
变量在 Linux 和 Windows 上的长度相同,肯定是什么地方出错了。main(方法 3 和方法 4 )的相关部分的反汇编如下所示:
方法 3 和方法 4("int *" 和 "long *")反汇编
0x8048ec0 : xor %esi,%esi
0x8048ec2 : cmp %edi,%esi
0x8048ec4 : mov 0xffffffdc(%ebp),%ecx
0x8048ec7 : mov 0xffffffd8(%ebp),%edx
0x8048eca : jae 0x8048f87
0x8048ed0 : mov (%edx),%eax
0x8048ed2 : add $0x4,%esi
0x8048ed5 : mov %eax,(%ecx)
0x8048ed7 : add $0x4,%edx
0x8048eda : add $0x4,%ecx
0x8048edd : cmp %edi,%esi
0x8048edf : jb 0x8048ed0
long *
0x8048ee8 : xor %esi,%esi
0x8048eea : cmp %edi,%esi
0x8048eec : mov 0xffffffdc(%ebp),%ecx
0x8048eef : mov 0xffffffd8(%ebp),%edx
0x8048ef2 : jae 0x8048f87
0x8048ef8 : mov (%edx),%eax
0x8048efa : add $0x4,%esi
0x8048efd : mov %eax,(%ecx)
0x8048eff : add $0x4,%edx
0x8048f02 : add $0x4,%ecx
0x8048f05 : cmp %edi,%esi
0x8048f07 : jb 0x8048ef8
"int *"
的速度变快了,而 "long *"
的速度却变慢了。使用相同的两个值,但通过交换代码的位置,性能也交换了。我得出的唯一结论就是代码一定是处于高速缓存的边界上。就象我们在上面看到的,没有两部分代码交叉的页边界。"int *"
和 "long *"
上的表现。在使用 "char *"
、 "short *"
和 "int *"
时,Windows 比例适中。每张图显示在内存传送性能方面 Windows 大约是 Linux 的两倍。Linux 在进行 4 字节传送时速度达到 600 MB/秒左右便停顿,无法再上升。这种现象的原因委实不清楚。
图 11. Linux 和 Win2k 中的 Memcpy
回页首
回页首
"double *"
方法在 Windows 上也更快。在所有其它的情况下,Linux 移动内存的速度好象更快。
发表评论
-
使用 RPM 打包软件,第 1 部分: 构建和分发包
2012-03-26 10:31 1252顾名思义,开源软件 ... -
用 RPM 打包软件,第 3 部分
2012-03-26 10:30 1151安装和卸载脚本的工作原理 安装和卸载脚本看起来很简单, ... -
用 RPM 打包软件,第 2 部分
2012-03-26 10:28 1151不作为 root 用户来构建 RPM 包 正如您在第 1 ... -
用 RPM 打包软件,第 1 部分
2012-03-26 10:23 976RPM(Red Hat Package Manager)是用于 ... -
Memory usage analysis
2010-09-03 23:33 1209Memory usage analysis Syste ... -
Linux: How to measure actual memory usage of an application or process?
2010-09-03 23:31 1275http://stackoverflow.com/questi ... -
HowTo: Profile Memory in a Linux System
2010-09-03 22:56 1177HOWTO: Profile Memory in a Li ... -
Linux内存管理机制
2010-09-03 22:48 2083内存是Linux内核所管理的最重要的资源之一,内存管理 ... -
linux内存管理概述
2010-09-03 22:44 2442Linux中的地址空间(一)有这么一系列的问题,是否在困扰 ... -
linux上buffer和cache的区别
2010-09-03 15:14 1519free free 命令相对于top 提供了更简洁的查看系统 ... -
linux下top命令参数解释
2010-09-03 14:56 864top命令是Linux下常用的性能分析工具,能够实时显示系统中 ... -
smem memory reporting tool
2010-08-25 15:41 966smem is a tool that can give ... -
Linux进程虚拟内存和物理内存
2010-08-25 15:39 5047先介绍几个基本概念: SIZE: 进程使用的 ... -
Memory: VSS/RSS/PSS/USS
2010-08-25 13:54 1527Terms VSS - Virtual Set ... -
Linux 内核的文件 Cache 管理机制介绍
2010-08-18 18:21 10481 前言 自从诞生以来,Linux 就被不断完善和普及 ... -
RunTime: 块内存复制
2010-08-06 12:32 1178内存复制 在计算机中,内存复制经常而普遍。它们出现在联网 ... -
内存详解
2010-08-06 11:34 930文档选项 ... -
Linux slab 分配器剖析
2010-08-06 11:32 1309良好的操作系统性能部分依赖于操作系统有效管理资源的能力。在 ... -
降低 Linux 内存开销
2010-08-06 11:30 1099Linux 广受追捧的一个优点是它比 Microsoft® ... -
在 Linux 平台中调试 C/C++ 内存泄漏方法
2010-08-06 11:29 1814由于 C 和 C++ 程序中完全由程序员自主申请和释放内存 ...
相关推荐
4. **内存块的移动**:易语言还提供了“移动内存块”命令,用于将内存块中的数据从一个位置复制到另一个位置,这在处理大块数据的复制或排序时非常有用。 5. **错误处理**:在进行内存操作时,易语言提供了“检查...
2. **分配内存**:使用`VirtualAlloc`函数在进程的虚拟地址空间中分配一块内存区域,用于存放从资源提取的数据。 3. **复制数据**:通过`LockResource`和`CopyMemory`(或`memcpy`)将EXE文件的内容从资源复制到新...
2. **内存读写**:`读内存`和`写内存`是两个关键的操作,用于在程序运行时读取或修改内存中的数据。这些操作需要配合内存地址和数据类型使用,确保数据正确无误地存取。 3. **内存复制与移动**:`复制内存`和`移动...
单片机实验上机--实验五 内存块移动为单片机实验的一部分,对于电子工程师和计算机科学家来说,了解单片机的基本原理和应用非常重要。本实验可以帮助学生更好地理解单片机的工作原理,并掌握基本的编程技术和实验...
2. 内存复制函数:查看源码如何调用"内存复制"命令,以及参数的设置,如源地址、目标地址和复制长度。 3. 性能基准:源码中应有记录和计算时间的代码,以评估不同内存复制操作的耗时。 4. 测试循环:可能包含各种...
4. **Java堆**(Heap): 这是JVM中最大的一块内存区域,所有对象实例和数组都在这里分配内存。堆内存是所有线程共享的,垃圾收集器的主要工作区域。Java堆可以被划分为新生代(Young Generation)和老年代(Tenured ...
例如,`创建内存块`函数用于在内存中分配指定大小的空间,`复制内存块`则可以将一块内存的内容复制到另一块内存,而`释放内存块`则是为了回收不再使用的内存,避免内存泄漏。 对于学生做毕业设计,这个资源包是一个...
例如,使用共享内存,两个或多个进程可以映射同一块内存,从而实现数据的快速交换。 在"文件内存中通讯源码例程"中,我们可以期待看到如何使用易语言的内存操作和IPC技术来实现这一功能。可能的步骤包括: 1. 读取...
4. **内存位图操作**:在复制透明块时,可能需要在内存中创建位图对象,然后进行位图的读取和写入操作,以实现块的复制。 5. **图形上下文**:理解Direct2D的设备上下文(ID2D1DeviceContext),它是进行2D绘图的...
易语言内存快速分割类模块提供了一个高效的内存复制功能,确保数据在复制过程中不发生错误。 3. **汇编加法与减法**: 汇编语言是底层编程的重要工具,它可以对内存中的数据执行加法和减法运算。在内存操作中,这...
写时复制是一种优化内存管理的技术,主要用于支持进程间共享只读内存区域,同时避免不必要的内存复制。在Linux中,当一个进程创建一个新的进程时,新进程最初会共享父进程的所有内存页。只有当其中一个进程尝试修改...
3. **共享内存**:多个进程可以共享同一块内存,减少内存的复制和提高效率。 4. **保留内存**:为特定硬件设备或系统服务预留的内存,不能被普通进程使用。 三、内存管理机制 AIX采用先进的内存管理策略,包括: ...
在第二个代码块中,使用内存映射技术复制文件。内存映射是指将文件映射到内存中,以便快速地读取和写入文件。通过使用CreateFileMapping和MapViewOfFile函数,可以创建文件映射对象,并将其映射到内存中。 三、多...
易语言内存模块通常包括动态内存分配、内存释放、内存复制、内存清零等功能。通过对内存块的申请、释放进行控制,实现高效的数据存储和处理。 3. **内存分配策略**: - 预分配:在程序启动时预留一部分内存,避免...
- **堆上分配**:又称动态内存分配,通过`malloc`或`new`在程序运行时动态申请内存。程序员需要自行管理这些内存,何时使用`free`或`delete`进行释放。这种方式灵活性高,但管理不当容易导致内存泄漏或悬挂指针。 2...
4. 内存复用:避免不必要的内存复制,重用已分配的内存块,减少内存碎片。 5. 内存预分配:预先为大对象分配内存,避免因动态分配导致的系统抖动。 了解了这些基础知识后,我们可以使用各种工具进行内存监控和优化...
3. **内存复制与移动**:在处理数据时,可能需要复制或移动内存中的数据,易语言提供了相应的函数,如`复制内存`和`移动内存`,用于高效地完成这些操作。 4. **内存安全**:为了防止非法访问内存,易语言有其自身的...
内部碎片是指分配给进程的内存中有未使用的部分,而外部碎片则是内存空闲空间不足以分配新的大块内存。解决碎片的方法有最佳适配、最差适配和首次适配等内存分配策略,以及紧凑操作,即将内存中的空闲块集中起来。 ...
- C语言中的`void *`类型可以用来存储任何类型的内存地址,`memcpy()`函数可以用来复制内存块,`malloc()`和`free()`用于动态内存分配和释放。 - 在C++中,`std::shared_ptr`和`std::unique_ptr`智能指针提供了...
2. **内存复制与移动**:通常,内存模块会提供函数用于内存块的复制(如`memcpy`)和移动(如`memmove`)。这些函数确保在内存操作中不会发生数据破坏,尤其是在处理重叠区域时。 3. **内存比较**:`memcmp`函数是...