我正在研究軟實時事件處理系統。我想盡量減少我的代碼中有非確定性時間的電話。我需要構造一個由字符串,數字,時間戳和GUID組成的消息。可能是boost::variant
的std::vector
的。關於使用和濫用alloca
我一直想在以前的代碼中使用alloca
。然而,當我們研究系統編程文獻時,總會對這個函數調用提出大量的警告。就我個人而言,我無法想象過去15年來沒有虛擬內存的服務器類機器,並且我知道Windows堆棧一次只增加一個虛擬內存頁面,所以我假設Unices也是如此。這裏再也沒有磚牆了,堆棧和堆一樣可能用盡空間,所以給了什麼?爲什麼人們不會通過aloca來加盟?我可以想到很多負責使用alloca的用例(字符串處理任何人?)。無論如何,我決定測試性能差異(見下文),並且alloca和malloc之間存在5倍的速度差異(測試捕獲了我將如何使用alloca)。那麼,有沒有改變?只要我們能夠絕對確定我們物體的壽命,我們是否應該謹慎行事並使用alloca
(包裹在std::allocator
中)?
我厭倦了生活在恐懼之中!
編輯:
好了,所以有限制,對於Windows是一個鏈接的時間限制。對於Unix來說,它似乎是可調的。它似乎是一個頁面對齊的內存分配器是爲了:D任何人都知道一個通用的便攜式實現:D?
代碼:
#include <stdlib.h>
#include <time.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace boost::posix_time;
int random_string_size()
{
return ((rand() % 1023) +1);
}
int random_vector_size()
{
return ((rand() % 31) +1);
}
void alloca_test()
{
int vec_sz = random_vector_size();
void ** vec = (void **) alloca(vec_sz * sizeof(void *));
for(int i = 0 ; i < vec_sz ; i++)
{
vec[i] = alloca(random_string_size());
}
}
void malloc_test()
{
int vec_sz = random_vector_size();
void ** vec = (void **) malloc(vec_sz * sizeof(void *));
for(int i = 0 ; i < vec_sz ; i++)
{
vec[i] = malloc(random_string_size());
}
for(int i = 0 ; i < vec_sz ; i++)
{
free(vec[i]);
}
free(vec);
}
int main()
{
srand(time(NULL));
ptime now;
ptime after;
int test_repeat = 100;
int times = 100000;
time_duration alloc_total;
for(int ii=0; ii < test_repeat; ++ii)
{
now = microsec_clock::local_time();
for(int i =0 ; i < times ; ++i)
{
alloca_test();
}
after = microsec_clock::local_time();
alloc_total += after -now;
}
std::cout << "alloca_time: " << alloc_total/test_repeat << std::endl;
time_duration malloc_total;
for(int ii=0; ii < test_repeat; ++ii)
{
now = microsec_clock::local_time();
for(int i =0 ; i < times ; ++i)
{
malloc_test();
}
after = microsec_clock::local_time();
malloc_total += after-now;
}
std::cout << "malloc_time: " << malloc_total/test_repeat << std::endl;
}
輸出:
[email protected]:~/test$ ./a.out
alloca_time: 00:00:00.056302
malloc_time: 00:00:00.260059
[email protected]:~/test$ ./a.out
alloca_time: 00:00:00.056229
malloc_time: 00:00:00.256374
[email protected]:~/test$ ./a.out
alloca_time: 00:00:00.056119
malloc_time: 00:00:00.265731
- 編輯:家用機,鐺,和谷歌的結果perftools--
G++ without any optimization flags
alloca_time: 00:00:00.025785
malloc_time: 00:00:00.106345
G++ -O3
alloca_time: 00:00:00.021838
cmalloc_time: 00:00:00.111039
Clang no flags
alloca_time: 00:00:00.025503
malloc_time: 00:00:00.104551
Clang -O3 (alloca become magically faster)
alloca_time: 00:00:00.013028
malloc_time: 00:00:00.101729
g++ -O3 perftools
alloca_time: 00:00:00.021137
malloc_time: 00:00:00.043913
clang++ -O3 perftools (The sweet spot)
alloca_time: 00:00:00.013969
malloc_time: 00:00:00.044468
似乎,啓用優化的叮噹測試是錯誤的。對alloca的內部調用被優化(刪除),因爲沒有副作用(在llvm IR代碼級別)或其結果的使用。 – osgx 2011-05-18 01:53:28
我曾經與傢伙(EE's)合作過,他們曾經構建商用嵌入式系統中使用的硬件,如有線公司網關。他們分配了一個固定大小的緩衝區,然後重新使用它。從未進入內存管理器。 – jww 2015-07-27 05:39:28