Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
哪种分配更快?malloc与局部变量_C_Linux_Gcc_Malloc - Fatal编程技术网

哪种分配更快?malloc与局部变量

哪种分配更快?malloc与局部变量,c,linux,gcc,malloc,C,Linux,Gcc,Malloc,对于经常分配和释放内存的函数,哪种方法更适合分配内存?假设这个函数在1GHz处理器上每秒被调用500到1000次 (请忽略静态和全局变量/分配。我只对这种特定情况感兴趣:) 或 局部变量基本上是“免费”分配的,所以如果我们只对性能感兴趣,这里就没有竞争 然而: 在本地变量和堆分配变量之间的选择通常不是您可以自由决定而不受约束的;通常有一些因素要求你做出选择,所以你的问题有点可疑,因为它似乎忽视了这个问题 虽然堆栈上的分配在性能上是“自由”的,但堆栈上的空间可能会受到限制(当然512字节是零)

对于经常分配和释放内存的函数,哪种方法更适合分配内存?假设这个函数在1GHz处理器上每秒被调用500到1000次

(请忽略静态和全局变量/分配。我只对这种特定情况感兴趣:)


局部变量基本上是“免费”分配的,所以如果我们只对性能感兴趣,这里就没有竞争

然而:

  • 在本地变量和堆分配变量之间的选择通常不是您可以自由决定而不受约束的;通常有一些因素要求你做出选择,所以你的问题有点可疑,因为它似乎忽视了这个问题
  • 虽然堆栈上的分配在性能上是“自由”的,但堆栈上的空间可能会受到限制(当然512字节是零)

堆栈分配比
malloc
+
free
更快


堆栈分配通常在指令中进行度量,而
malloc
+
free
可能需要多个锁(这是比较耗时的一个例子)。

局部变量的堆栈分配比使用
malloc
的堆分配更快。但是,总堆栈空间是有限的(例如,数兆字节)。因此,您应该将自己限制为本地堆栈上的“小”数据。(按照今天的标准,512字节很小,但256Kb对于本地堆栈分配来说太大了)

如果您的函数是非常深入的递归函数,那么即使512字节也可能太大,因为每个递归调用帧都需要512字节

但是每秒调用
malloc
几千次应该是无痛的(典型的小型
malloc
需要几十微秒)


出于您的好奇心,在C世界之外,您可能会对A.Appel的旧论文感兴趣(但缓存性能方面的考虑可能会削弱这一说法)

局部变量的情况会快得多:在堆栈上分配变量不需要额外的时间,它只会更改堆栈指针的移动量。而malloc将不得不做一些簿记

  • 哪种方法更适合分配内存
  • 哪种分配更快
你想要更快的方式,还是更好的方式

无论如何,在你提到的情况下,我认为第二种选择:

struct MyStruct localvar;
更高效,因为内存分配是由堆栈完成的。与使用动态内存分配函数(如
malloc
)相比,哪种方法更有效

优化 此外,如果您这样做是为了性能和优化

在我的电脑上,使用
malloc
来分配字符串,而不是从堆栈中声明一个字符数组,给了我每个字符串大约73纳秒的延迟

如果在程序中复制了50个字符串: 4757142/50=95142(和一点点)运行您的程序

如果我每天运行您的程序50次: 95142/50=1902(和一点)天

1902天=5年半


因此,如果你每天运行你的程序5年零2个月,你将节省额外的眨眼时间。哇,多么值得…

使用堆栈的另一个优点是它不会分割内存空间,而malloc通常会这样做。当然,这只是长时间运行的进程的一个问题。

在输入函数时打开反汇编程序,并逐步完成这两种情况

局部变量(基于堆栈)将需要0个额外的周期——您甚至看不到分配来自何处,因为函数将仅通过移动堆栈指针在1个周期内分配所有局部变量,并通过还原堆栈指针在1个周期内释放所有局部变量。不管您有1个或1000个局部变量,“分配”所花费的时间是相同的

malloc变量。。。好的,您很快就会感到厌烦,单击单步执行数千条指令以从系统堆中获取内存。除此之外,您可能会注意到,周期的数量因调用而异,这取决于您已经从堆中分配了多少内容,因为每次请求内存时,malloc都需要对堆结构进行“搜索”


我的经验法则:如果可能,请始终使用堆栈,而不是
malloc/free
new/delete
。除了更快的性能,您还可以不必担心内存或资源泄漏。在C中,这意味着忘记调用<代码>()(代码)>,但是在C++异常中,如果在调用“代码>删除< /代码>之前抛出异常,就会破坏您的一天。如果您使用堆栈变量,这一切都会自动处理!但是,只有在谈论“小”内存块(字节和KB)而不是大对象(不是MB或GB!)时才使用堆栈。如果你谈论的是巨大的对象,那么你就不再谈论性能了,你可能不会在同一个函数调用中调用
free/delete

但是如果我有一个图形应用程序,它的函数每帧调用100万次(例如
sin
,非常常见)。现在,突然之间,我每帧花费0.073秒
malloc
'ing,给了我13帧的最大FPS!不是你想要的,是73纳秒,不是73毫秒。1ms=1000000ns.+1指出本地和堆分配有两种不同的用途,比较它们没有多大意义。智能垃圾至少可以和堆栈分配一样快,但很难做到正确。在GC中构建的语言有很多技巧,使它的行为更像一个堆栈,但我不确定如何在C中复制它,因为它往往涉及到能够轻松地移动东西(这会导致一个级别的错误)
void Test()
{
     struct MyStruct localvar; // 512 byte sized structure
     ... 
}
struct MyStruct localvar;