当我们使用malloc()分配内存时,我们应该给出两个幂的大小吗?或者我们只是给出我们需要的确切尺寸?
喜欢
//char *ptr= malloc( 200 );
char *ptr= malloc( 256 );//instead of 200 we use 256
Run Code Online (Sandbox Code Playgroud)
如果给出2的幂的大小更好,那是什么原因?为什么更好?
谢谢
编辑
我混淆的原因是在Joel的博客Back to Basics中引用
智能程序员通过始终分配大小为2的内存块来最小化malloc的潜在破坏.你知道,4个字节,8个字节,16个字节,18446744073709551616个字节等.由于任何使用乐高的人都应该直观的原因,这可以最大限度地减少自由链中发生的奇怪碎片的数量.虽然看起来这似乎浪费了空间,但也很容易看出它永远不会浪费50%以上的空间.所以你的程序使用的内存不会超过它需要的两倍,这不是什么大不了的事.
对不起,我应该早点发布上面的报价.我很抱歉!
到目前为止,大多数回复都说,以2的力量分配内存是一个坏主意,那么在哪种情况下更好地遵循Joel的观点malloc()呢?他为什么这么说?以上引用的建议现在已经过时了吗?
请解释一下.
谢谢
在阅读了以下论文后,https://people.freebsd.org/~lstewart/articles/cpumemory.pdf("每个程序员应该了解内存的内容")我想尝试一下作者的测试,即测量效果TLB的最终执行时间.
我正在研究嵌入Cortex-A9的三星Galaxy S3.
根据文件:
我们在L1中有两个用于指令和数据缓存的微TLB(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/Chddiifa.html)
主要TLB位于L2(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/Chddiifa.html)
Data micro TLB有32个条目(指令微TLB有32或64个条目)
我写了一个小程序,用N个条目分配一个结构数组.每个条目的大小为== 32个字节,因此它适合缓存行.我执行几次读取访问,并测量执行时间.
typedef struct {
int elmt; // sizeof(int) == 4 bytes
char padding[28]; // 4 + 28 = 32B == cache line size
}entry;
volatile entry ** entries = NULL;
//Allocate memory and init to 0
entries = calloc(NB_ENTRIES, sizeof(entry *));
if(entries == NULL) perror("calloc failed"); exit(1);
for(i = 0; i < NB_ENTRIES; i++)
{
entries[i] = mmap(NULL, …Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用mremap().我希望能够以高速移动虚拟内存页面.至少比复制它们更快的速度.我有一些算法的想法,可以利用能够快速移动内存页面.问题是,下面的程序显示mremap()非常慢 - 至少在我的i7笔记本电脑上 - 与实际逐字节复制相同的内存页面相比.
测试源代码如何工作?mmap()256 MB的RAM比CPU高速缓存大.迭代20万次.在每次迭代时,使用特定的交换方法交换两个随机内存页面.使用基于mremap()的页面交换方法运行一次和时间.使用逐字节复制交换方法再次运行和时间.事实证明,mremap()每秒仅管理71,577次页面交换,而逐字节复制每秒管理高达287,879次页面交换.所以mremap()比逐字节复制慢4倍!
问题:
为什么mremap()这么慢?
是否有另一个user-land或kernel-land可调页面映射操作API可能更快?
是否有另一个user-land或kernel-land可调页面映射操作API允许在一次调用中重新映射多个非连续页面?
是否有任何内核扩展支持这种事情?
#include <stdio.h>
#include <string.h>
#define __USE_GNU
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <asm/ldt.h>
#include <asm/unistd.h>
// gcc mremap.c && perl -MTime::HiRes -e '$t1=Time::HiRes::time;system(q[TEST_MREMAP=1 ./a.out]);$t2=Time::HiRes::time;printf qq[%u per second\n],(1/($t2-$t1))*200_000;'
// page size = 4096
// allocating 256 MB
// before 0x7f8e060bd000=0
// before 0x7f8e060be000=1
// before 0x7f8e160bd000
// after 0x7f8e060bd000=41
// after 0x7f8e060be000=228
// 71577 per second
// gcc mremap.c && perl -MTime::HiRes -e '$t1=Time::HiRes::time;system(q[TEST_COPY=1 ./a.out]);$t2=Time::HiRes::time;printf qq[%u …Run Code Online (Sandbox Code Playgroud) 通常,列表既可以作为链接列表实现,也可以作为数组列表实现,这些列表在插入元素时很慢.
我想知道是否可以使用处理器的MMU更有效地实现列表,通过重新映射而不是在插入或删除元素时复制内存.这意味着数组中任何位置的索引和插入/删除都具有O(1)的速度,优于任何其他列表实现.
我的问题是:
我试图找出如何在Mac上重新映射内存映射文件(当我想扩展可用空间时).
我在Linux世界中看到了我们的朋友,mremap但我在Mac上的标题中找不到这样的功能./Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h有以下内容:
mmapmprotectmsyncmunlockmunmapmremapman mremap 证实了我的恐惧.
我目前不得不munmap,mmmap如果我想调整映射文件的大小,这涉及使所有加载的页面无效.肯定有更好的办法.一定?
我正在尝试编写适用于Mac OS X和Linux的代码.如果我不得不这样做,我可以满足于在每种情况下使用最佳功能的宏,但我宁愿正确地做到这一点.