Динамический размер массива С++

Тема в разделе "WASM.BEGINNERS", создана пользователем Enchantner, 31 окт 2008.

  1. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    AsmGuru62
    интересно - поиграюсь :) хотя небольшие временные массивы имхо лучше в стеке.

    Booster
    Конструкция vector <int> v1; v1.reserve( N ); порождает монстра типа new.
    Но похоже у меня был глюк когда я посмотрел на релиз кода vector <int> v1 (N); и решил что он похож на #4, наверно глянул невнимательно и не заметил call...

    SadKo
    реализации alloca тоже ох как дааалеко до sub esp, sizeBuffer... ну ладно бы там 5-7 лишних команд было или проверка переполнения какая толковая реализована, а то мусора много, толку мало (хотя на фоне new конечно вполне прилично). Что и её переписывать? я бы с радостью, но непонятно как это сделать средствами С++ без апи и асм вставок.

    ЗЫ: Короче картина в общем ясна - хвалёная низкоуровневая оптимизация современных копиляторов не только не оптимизирует FPU кода, но ещё и тщательно компенсируется дико затратными стандартными и библиотечными конструкциями языка.
    Настоящий дзен живёт только в асме :))
     
  2. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Может ты просто забыл поиграться с ключами оптимизации? Лично я никаких проблем даже с FPU-кодом не замечал. А если что не устраивало - писал свою реализацию.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    SadKo
    Visual C++ 2005 release /O2
    локальную float каждый раз кидает в память в конце цикла и тут же извлекает обратно в начале. Но это так присказка не по теме.
    Лучше подскажи какая С++ конструкция скомпилится в #4? согласен даже на десяток лишних команд в придачу...
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Y_Mur
    Выдели большой кусок памяти, сделай из него свой стек и будет тебе счастье.
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Booster
    Это понятно: свой стек, своя heap, свой компилятор... :)))
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Y_Mur
    С++ это же язык для создания других языков. ) Я бы наверно сделал так: Сделал бы класс синглтон - "менеджер стека", который бы хранил указатель на дно выделенной памяти. Сделал бы вспомогательный класс - стек, который бы хранил указатель на свою память в стеке. Например объявляешь переменную "стек" передавая в конструктор размер необходимой памяти. "Стек" в конструкторе обращается к менеджеру и запрашивает у него необходимый кусок памяти. Когда происходит выход их блока, автоматические переменные "стек" уничтожаются, попутно обращаясь к менеджеру за освобождением памяти. Получается аналог AutoPtr.
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Booster
    спасибо понятно - хочешь чтобы было хорошо сделай сам с нуля ;)) впрочем это везде, не только в С++ :)))
     
  8. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Ты думаешь этот "мусор" просто так напихан? Попробуй-ка выделить килобайт сто своим sup esp, тогда может дойдёт зачем тот "мусор".
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    reverser
    Хм - забавно - на асме:
    Код (Text):
    1.     sizeBuf = 100*1024
    2.     sub esp, sizeBuf
    3.     xor esi, esi
    4.     @@:
    5.       mov [esp + esi], ecx
    6.       add esi, 4
    7.       cmp esi, sizeBuf
    8.     jnbe @B
    9.     add esp, sizeBuf
    действительно обламывается при первом же обращении к памяти в стеке, а если подбираться к в десять раз большему размеру буфера последовательно через push или так:
    Код (Text):
    1.     sizeBuf = 1000*1024
    2.     sub esp, sizeBuf
    3.     mov esi, sizeBuf
    4.     @@:
    5.       mov [esp + esi], esi
    6.       sub esi, 4
    7.     jnbe @B
    8.     add esp, sizeBuf
    всё работает нормально (есно если хватает резерва стека - sizeBuf = 1024*1024 уже падает из-за его переполнения).
    Буду разбираться, кстати никаких лишних проверок во втором варианте нету, а всё равно работает :))
    add:
    И если первый код запустить после второго то он тоже работает, значит дело в том, что винда выделяет страницы стеку по мере необходимости и не любит пропуска страниц. Но сдаётся мне что проверку и корректирову такого случая всё равно можно и нужно сделать намного проще чем в alloca.
    Хотя я опять отвлёкся от темы, ведь С++ не позволит мне сделать свою alloca в общем стеке не прибегая к асм вставкам, которые придется как то "синхронизировать" с использованием стека самим компилятором, а это боюсь уже не совсем хорошо.
     
  10. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    попробуй так:
    Код (Text):
    1. namespace my_alloc
    2. {
    3.     inline void *operator new[](size_t size)
    4.     {
    5.         return alloca(size);
    6.     }
    7. }
    8.  
    9. void f(int n)
    10. {
    11.     int *items = my_alloc::new int[N];
    12. }
    По идее, должно работать, если my_alloc::new будет действительно инлайниться.
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    SadKo
    Имхо от переименования хипового new в стековую alloca будет только лишняя путаница в программе. Уж лучше её напрямую использовать (хотя она независимо от инлановости превышает лимит в 10 лишних команд ;) но не очень сильно так что пусть). А бороться с rtl-ной избыточностью new лучше через замену heap на апи-шную или свою.
    Подмена heap на стек ради скорости это совсем не дзен, у них разные области применения - heap для долгоживущих данных, которым совсем не место в стеке, но для небольших временных буферов стек быстрее, потому что поиск свободного блока в хипе, полюбому имеет больше накладных расходов, чем резервирование стека, даже если добавить к нему разумную проверку и исправление "граблей" с пропуском страниц памяти.