Об использовании и неправильном использовании alloca

Я работаю над системой обработки событий в мягком реальном времени. Я хотел бы минимизировать в моем коде столько вызовов, которые имеют недетерминированное время. Мне нужно создать сообщение, состоящее из строк, чисел, временных меток и GUID. Вероятно, std :: vector из boost :: variant .

Я всегда хотел использовать alloca в прошлом коде аналогичного характера. Однако, когда кто-то заглядывает в литературу по системному программированию, всегда есть серьезные предостережения против этого вызова функции. Лично я могу ' Я не думаю о машине серверного класса за последние 15 лет, у которой нет виртуальной памяти, и я точно знаю, что стек Windows наращивает виртуальную память на одну страницу за раз, поэтому я предполагаю, что Unices тоже . Здесь нет кирпичной стены (больше), в стеке не меньше места, чем в куче, так что же дает? Почему люди не сходят с ума по алоке? Я могу придумать множество вариантов ответственного использования alloca (кто-нибудь обрабатывает строки?).

Так или иначе, я решил проверить разницу в производительности (см. Ниже), и есть 5-кратная разница в скорости между alloca и malloc ( тест показывает, как я буду использовать alloca). Итак, что-то изменилось? Должны ли мы просто выбросить осторожность и использовать alloca (завернутый в std :: распределитель ) всякий раз, когда мы можем быть абсолютно уверены в сроке жизни наших объектов?

Я устал жить в страхе!

Изменить:

Хорошо, есть ограничения, для окон это ограничение по времени ссылки. Для 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;
}

вывод:

hassan@hassan-desktop:~/test$ ./a.out 
alloca_time: 00:00:00.056302
malloc_time: 00:00:00.260059
hassan@hassan-desktop:~/test$ ./a.out 
alloca_time: 00:00:00.056229
malloc_time: 00:00:00.256374
hassan@hassan-desktop:~/test$ ./a.out 
alloca_time: 00:00:00.056119
malloc_time: 00:00:00.265731

- Изменить: результаты на домашней машине, clang и google 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
20
задан Hassan Syed 28 April 2011 в 14:53
поделиться