воскресенье, 8 апреля 2012 г.

Memory Managment Framework. Постановка задачи

Давненько ничего не писал и вот решил исправится. Тем более, что на выходных в голову пришла неплохая тема.
Сразу оговорюсь, что в данном опусе будут только мои мысли и разглагольствования, по-сути просто постановка задачи.  Если хватить упорства, то решение задачи я выложу позжее. И еще мой опыт опирается только на разработку игр, поскольку в своей жизни я больше ничего не писал. Возможно у вас все по-другому :).

Одним из слабых (или сильных) сторон C++ является необходимость разработчикам полностью брать в свои руки управление памятью во время работы приложения. Не у всех это удается одинаково хорошо. Отсюда исходят стандартные проблемы: утечки памяти и фрагментация. Как результат не всякое приложение может проработать больше десятка часов без потерь памяти.
Собственно наша игра на данный момент испытывает теже проблемы. Мы потихоньку правим и улучшаем, но возникает вопрос: а нельзя ли чтобы сразу было хорошо? Ведь в мире существует множество движков, библиотек и фреймворков, которые позволяют разработчикам избежать множество проблем. Неужели нет чего-то подобного для управления памятью.
Размышляя на эту тему я попробовал ответить на ряд вопросов:
  1. Что бы дало наличие такой библиотеки
  2. Какие возможные неудобства и ограничения она бы принесла
  3. Какие требования могут быть к такой библиотеке
Пойду по-порядку и постараюсь изложить все что мне пришло в голову.
 
    Возможности, которые я хотел бы видеть в данной библиотеке. 

  • Различные виды аллокаторов памяти. Если вы до сих пор работали с памятью в стиле ПК (т.е. используя стандартные операторы new/delete), то обязательно найдите кого-то, кто работал на консолях и расспросите его. Многие SDK для консолей уже содержат реализации нескольких видов аллокаторов, которые часто работают эффективнее стандартного. 
  • Дальше такая библиотека дала бы больше возможностей для контроля и отладки расхода памяти: создание дампов, проверка ликов, запись логов и возможность получать карту памяти приложения в любой момент времени и т.д. 
  • Намного более жесткий контроль за выделением памяти. Для многих программистов это является хорошей школой, особенно в наш век Java и C#. Слишком многие свысока относятся к гигабайтам свистящим у виска. Такой контроль позволит установить константный объем памяти, которая будет необходима вашему приложению. 

Собственно тут можно напридумывать много чего. Ограничений нет. Ведь вы полностью контролируете работу с памятью.

    Ограничения и неудобства в работе
Конечно в самом идеальном случае при работе с такой библиотекой ничего не поменяется. Но все же из моей практики может возникнуть ряд проблем.

  • Скорее всего придется отказаться от стандартных операторов new/delete, а ново введенные не будут обладать той же лаконичностью и красотой.
  • Возможно придется определять работу с памятью для каждого класса, т.е. переопределять операторы new/delete для каждого класса.
  • Вам понадобится затратить время на обучение всей команды новым правилам работы с памятью. Причем нужно будет донести не только новый синтаксис, но и понимание новых принципов выделения и освобождения памяти. Иначе счастья не будет. 
  • Могут возникнуть проблемы со сторонними библиотеками и фреймворками. Особенно, если у вас нет их исходников.


    Требования к библиотеке
Требования я разделил на две части. Обязательные и прикольные.
Обязательные:
  • Надежность - любыми способами необходимо гарантировать, что функционал библиотеки под любыми нагрузками будет работать только так, как задумано и описано в документации.
  • Скорость - скорость работы для стандартного аллокатора в релизе должна быть как минимум такой же, как и у стандартной реализации операторов new/delete. 
  • Многопоточность - библиотека должна работать из нескольких потоков. На самом деле это очень интересный момент, с кучей своих кейсов и ньюансов. 
  • Низкая точка старта - по умолчанию библиотека должна работать как стандартные операторы new/delete и не требовать сложной настройки. Естественно все инструменты также должны подхватываться сразу, а не после недели танцев с бубнами.
Прикольные:
  • Кроссплатформенность - большая часть кода библиотеки платформонезависима. Но есть несколько точек, где не избежать взаимодействия с конкретной системой: захват памяти у системы и ее освобождение. Также некоторые платформы имеют несколько типов памяти и могут по-разному с ними работать. 
  • Интеграция с популярными IDE - тут опять подключаем фантазию. Можно представить красивые графики в VisualStudio или Eclipse.
 
     Вот собственно почти все к чему пришел. Также в качестве дальнейших, и более практических, шагов записал следующие вопросы:
  • А есть ли уже готовые решения данной задачи (после 15 минут в гугле почти ничего не нашел)?
  • Как работают стандартные реализации операторов new/delete?
  • Какие решения сделаны в рамках различных игровых движков (OGRE, Torque, Unreal, CryEngine и т.д.)?
  • Насколько сложно самому реализовать текую библиотеку и зачем оно мне нужно?
Если можете поделиться информацией буду премного благодарен.
Всем доброй ночи

четверг, 22 марта 2012 г.

Perforce: edit, add, delete в командной строке


      Всем привет.
      Сегодня наткнулся на интересный способ для автоматического добавления файлов на редакторивание в perforce, пришлось править, и потому решил сразу написать для себя и будущих поколений небольшую подсказку-памятку.
      Задача очень простая. В депоте хранится клиент в распакованном виде, т.е. так как он будет лежать на машине у пользователей. При сборке новой версии нужно переписывать измененные файлы, добавлять новые, и, по-возможности, удалять старые.
      Как раз третий шаг у нас и не выполнялся. Итак, что было?
      Сборка шла по следующим шагам:
  1. Удаление локальной версии;
  2. Копирование на ее место новой, только собранной версии клиента;
  3. Добавление на чекаут измененных файлов;
  4. Добавление новых файлов;
  5. Коммит изменений на сервер.
      Как видим удаления нет. Некоторое время это было не критично, но вот пришлось править.
      Недолго думая я решил, что после чекаута измененных файлов необходимо вставить код, который будет удалять в депоте файлы, отсутствующие локально. Вроде все просто. Добавил команду, между 3 и 4 шагами, и... обломался. Не было удалено ни одного файла, хотя пару кандидатов на примете у меня было.
      Причина оказалась банальна. На 3 шаге был вот такой вот код:
   
            p4 edit \\depot\client\...
            p4 revert -a -c
       
      Т.е. сначала на редактирование брались тупо все файлы, а потом делался реверт тех файлов, которые не были изменены. Особенность perforce (да наверное и любой другой системы контроля версий ) такова, что при реверте локальный файл восстанавливается. Другими словами, даже если в сборке и не хватало файлов, то после этой команды они восстанавливались из депота и мой шаг по удалению ничего не находил.
      Вот эту штуку и пришлось править. В perforce есть хорошая команда, которая позволяет отобрать уже только измененные файлы и взять на редактирование только их. Она же позволяет находить файлы, которые нужно удалить в депоте.
      После небольшой правки скипт стал выглядеть примерно так:

            echo "DELETE MISSED FILES"
            p4 diff -sd \\depot\client\... | p4 -x - delete
         
            echo "CHECKOUT CHANGED FILES"
            p4 diff -se \\depot\client\... | p4 -x - edit
         
            echo "ADD NEW FILES IN PERFORCE"
            cd /d D:/p4/client
            dir /b /s /a-d | p4  -x - add -f

      Все просто и наглядно.
      Ну а потом делаем коммит на сервер. Референс на все команды perforce можно глянуть тут: http://www.perforce.com/perforce/doc.current/manuals/cmdref/index.html
      Всем доброй ночи.

понедельник, 19 марта 2012 г.

Анализ дня: недостаток perforce, мобильная разработка на Unity

    Всем привет.
    Сегодня снова две темы дня. И более практических, чем обычно.
    Начнем с Perforce. С этом системой я проработал больше 3-х лет и, за все время, особых нареканий у меня не было. Хотя периодически были проблемы. Так сложилось, что последний год я просидел на паре Svn, Mercurial и только месяц назад пришел на проект, где используется Perforce. База на проекте уже огромная - под сотню гигабайт. Файлы самые разные по размерам, от нескольких байт до пары гигабайт. Самое главное, что их много, очень много. Думаю за полмиллиона уже перевалили.
     Оказалось, что Perforce справляется с таким репозитарием очень туго. Тормозит, появляются ошибки. Например файл регистрируется в базе, но на сервер не попадает. И все, кто пытается обновится, получают предупреждение о том, что файл отсутствует.
     На фоне данной проблемы и вылез, как мне кажется, главный недостаток Perforce по сравнению с остальными системами - Perforce требует подключения к серверу и ответа от сервера для выполнения любой команды. Абсолютно любой.
     Во время работы программист наиболее часто выполняет 3 операции: обновление с сервера, коммит на сервер и чекаут файла. Так вот, если у вас тормозит сервер, то вы можете обновляться и коммитить файлы, пусть и со скрипом. Это не такие частые операции, пару раз в день, а у кого-то и реже. Но вот чекаут файла это жизненно необходимая операция, без нее работать чуть хуже чем никак. SVN берет эту заботу на себя и не требует подключения к серверу, Git и Mercurial вообще не требуют сервера, а вот Perforce требует ответа от сервера.
     Итог грустен: невозможность взять файл на чекаут тупо блокирует работу, срывает настрой и вдохновение.

     Вторая тема более жизнерадостная. Как я уже писал, Unity раздает лицензии на мобильные платформы бесплатно. Я воспользовался возможностью и получил свою лицензию. На выходных начал писать аж две программки для Android. Первая это порт игры Smash Aliens (линк на youtube), а вторая - это программа для тренировок, я назвал ее TrainerBoo.
     В данном случае, можно воспользоваться одним из плюсов Unity и погонять оба моих не доделанных приложения через браузер. Вот Aliens, а вот TrainerBoo.
     Собственно меня теперь волнуют два вопроса:

  1. Размер финального приложения - apk файл для Aliens занимает больше 10MB, а для TrainerBoo - больше 6MB (там вообще нет моих ресурсов, только Unity) 
  2. Производительность на Unity

     По ходу развития проектов поделюсь тем как ведет себя Unity.

     Всем доброй ночи.