2012-02-29 2 views
3

Это на самом деле содержит 2 вопроса.Как вы справляетесь с ограничениями памяти и улучшением производительности процесса.

1) Вам предоставляется проект, который, как оказалось, создает код, который не может соответствовать ограничениям памяти среды. Что вы можете сделать, чтобы справиться с этим?

2) Вам предоставляется проект, который оказался медленным, чем ожидалось. Как вы справляетесь с этим?

ответов, которые я мог думать о:

1) Использование зЬх библиотек как можно больше, потому что, вероятно, они будут загружены в любом случае, Модуляризацией кода с функциями, чтобы избежать перезаписей повторяющегося кода, который может законсервировать пространство стека.

2) Представляя встроенные функции везде, где это необходимо, чтобы сократить накладные расходы на функции, оптимизация компилятора может быть (если не я использую volatile)?

Пожалуйста, дайте как можно больше возможных решений, как это возможно :)

ответ

7

Вам дается проект, который оказался для получения кода, который не может соответствовать ограничениям, памяти окружающей среды. Что вы можете сделать, чтобы справиться с этим?

Определить, сколько коды след разрешено, а затем применять различные code refactoring methods для уменьшения тока след, чтобы соответствовать допустимому размеру.

Вам предоставляется проект, который оказался медленным, чем ожидалось. Как вы справляетесь с этим?

профиль проекта найти узкие места в производительности, в выявленных узких местах, определить 20% общего код, который работает 90% времени exectuion проекта, а затем целевым этот код для оптимизации.

+4

+1 для правила 90-20 ??? :) –

+0

Очень интересно услышать правило 90-20. Для получения дополнительной информации: http://en.wikipedia.org/wiki/Pareto_principle –

4

1) Динамическая загрузки и выгрузки модулей по мере необходимости.

Под Windows вы можете использовать LoadLibrary и GetProcAddress вместо фактической ссылки на файл lib. Связывание вызывает загрузку dll в память, даже если не используется. С LoadLibrary вы можете загрузить его, когда вам это нужно, чтобы он не занимал память, а затем выгружал его, когда это было сделано.

Для Linux см. Раздел this link, раздел «Динамическая загрузка и разгрузка разделяемых библиотек с использованием libdl».

2) Профиль, конечно. Если собеседник не задает вопросы об оптимизации микро-оптимизации, это правильный ответ.

+0

'В Windows вы можете использовать LoadLibrary и GetProcAddress вместо фактической ссылки на файл lib. Связывание приводит к тому, что dll загружается в память, даже если не используется. «Любой эквивалент в Linux? – Thunderman

+0

@Thunderman Я не знаю. –

+0

@Thunderman Я нашел что-то, может помочь. Я отредактировал свой ответ. –

0
  1. Убедитесь, что вы COMDAT Свёртывать, АКД и устранение неиспользованной функции является обязательным. Устраните ненужные зависимости, используйте инструменты покрытия кода и рефакторинг, чтобы избежать дублирования. Запуск профилировщика памяти также поможет, тогда вы сможете определить области, которые больше всего нуждаются в фиксации. Большинство компиляторов также дают возможность оптимизировать размер вместо скорости.

  2. Используйте профайлер, чтобы вы знали , почему не работает правильно, а не просто гадает.

1

1) Вам предоставляется проект, который, как оказалось, создает код, который не может соответствовать ограничениям памяти среды. Что вы можете сделать, чтобы справиться с этим?

вопрос, как просили говорит «код» не может поместиться ... что, если в буквальном смысле (т.е. как в отличие от стека, кучи и статических/глобальных данных) означает:

1) некоторые необходимо уменьшить размер исполняемого кода и/или 2) необходимо уменьшить объем загружаемого кода и/или 3) ограничения необходимо снять.

Вопрос может или не допускать 3) - рассмотрение ограничения. Если собеседник вдохновляет, начните там, так как это легко победить: например. можете ли вы перекомпилировать 16-разрядный процесс как 32-разрядный или указать другой исполняемый макет компилятору/компоновщику, чтобы увеличить поддерживаемый размер исполняемого файла? Можете ли вы увеличить виртуальное адресное пространство, назначив еще один жесткий диск для замены места, не сталкиваясь с чрезмерной заменой?

К 1) уменьшить размер кода, начать с его измерения: как в целом, так и на основе каждой функции. Проверьте, чтобы коммутаторы компилятора оптимизировали пространство по скорости и их влияние. На уровне каждой функции сосредоточьтесь на самых больших функциях и в любых случаях, когда множество подобных функций объединяет много исполняемого кода. Такие функции могут генерироваться вложенными макросами или из некоторого инструмента генерации кода. Попробуйте включить общий алгоритм в одну функцию, которая принимает настройки с помощью указателей функций или переключения времени выполнения.

Прочитайте наиболее проблемные функции для возможных причин раздувания, таких как потенциально встроенные функции, которые они называют массой времени. В то время как вызовы функций могут быть немного хуже, чем встроенный код для очень простых операций, повторная вставка нетривиальных функций может создать произвольно худший код раздувания. Макровы расширения препроцессора внутри функций также эффективно встраиваются.

Для 2) уменьшения одновременного загрузки кода вы можете использовать динамически загружаемые библиотеки (например, dlopen/dlsym/dlclose в Linux/UNIX). Это дает вам явное управление временными окнами, в которых код отображается в адресное пространство процесса. В качестве альтернативы вы можете эффективно сериализовать необходимость в частях кода, например. сначала запускается некоторая однократная генерация данных, подготовка данных для последующего использования процесса. Или, в зависимости от вашей ОС и ограничений, вы можете одновременно запускать части программы на одном и том же или разных хостах и ​​обмениваться данными с помощью механизмов IPC, таких как разделяемая память или сеть.

Конечно, возможно, что «код» использовался невольно в вопросе, а реальной проблемой является изнурение кучи или даже истощение усталости - существуют разные методы обращения к ним, но не хотят отвлекаться на спекуляции ,

2) Вам предоставляется проект, который оказался медленным, чем ожидалось. Как вы справляетесь с этим?

Во-первых, необходимо определить причину и тип медлительности:

  • ли проект I/O связаны, ЦП, жесткого кодирования задержки между шагами (это происходит, в частности, в экране скремблирование приложений, где более масштабируемый, надежный подход не был разработан заранее), страдает от задержки планирования и т. д.
  • Тогда - какой тип медлительности - латентность или пропускная способность?

Если проект связан с вводом-выводом, то многое зависит от устройства, в котором оно ожидает. Вы можете легко переиграть магнитный жесткий диск для SSD-накопителя или добавить RAM или обновить свою сетевую карту. Вы можете изменить способ ввода такого типа ввода-вывода, например, переход от несжатого к сжатым данным или наоборот, удаление ненужной очистки потока, создание индексов в передней части файлов, чтобы затем вы могли напрямую обращаться к необходимым вместо того, чтобы выполнять поиск по грубой силе, настраивая параметры Nagle для задержек TCP и пропускной способности, используя многоадресную передачу, а не много сетевых соединений «точка-точка», используя двоичные, а не XML-сериализацию или форматы данных, используя сопоставление памяти, предпочитая looping read() Ввод данных в локальные буферы. Возможно, вы сможете переосмыслить, как выполняется ввод-вывод, например. используя более эффективные и прямые индексы в памяти в данные диска, используя высококачественные хеш-функции и более редкие таблицы, а не двоичные поиски через отсортированные данные. Эти понятия, знакомые по своим эквивалентам в памяти (массивы и хэш-таблицы) от базовой вычислительной науки, могут иметь еще худшие последствия при использовании ввода-вывода.

Если проект связан с ЦП, то используйте профилировщик, чтобы увидеть, какие функции составляют большую часть времени. Manulaly добавляет дополнительную трассировку процессора и/или прошедшего времени внутри больших функций, пока вы не поймете причины. Как каждая проблема может быть исправлена ​​может сильно различаться, но некоторые общие вещи, чтобы проверить для оптимизации:

  • алгоритмической эффективности (например, избежать ненужного O (N^2) и хуже операций по нечетко или сколь угодно больших п)
  • ненужных копирование данных
  • не пересчитывая значения без необходимости, когда результаты более раннего расчета могут быть легко сохранены и использованы повторно (например, составление регулярных выражений затем использовать их один раз, несмотря на то, насущная потребность в точном-же регулярное выражение)
  • физической памяти ошибка страницы, сгенерированная вашим алгоритмическим кодом (наиболее актуальным для огромной матрицы от значений)

Кроме того, планирование может быть большой проблемой. Вы можете обнаружить, что атомарные операции выполняются с помощью мьютексов или необходимо изменить приоритеты процессов или привязки к ЦП или принять фундаментальное решение, например, использовать потоки vs select/poll для обработки нескольких клиентских подключений.

ответов, которые я мог думать о: 1) Использование зЬх библиотек как можно больше, потому что, вероятно, они будут загружены в любом случае, Модуляризацией кода с функциями, чтобы избежать перезаписей повторяющегося кода, который может законсервировать пространство стека.

Ярмарка достаточно.

2) Представляя встроенные функции везде, где это необходимо, чтобы сократить накладные расходы функции поиска, оптимизация компилятора может быть (если не я использую volatile)?

Определенно, на первый взгляд. В моих измерениях - в нескольких операционных системах/процессорах/компиляторах и т. Д. - встраивание тривиальных функций имеет тенденцию быть на порядок быстрее, чем вызов функции, но для более крупных функций встраивание может вызвать раздувание кода, что в средах с ограниченными ресурсами - в конечном итоге приводит к большему кеш отсутствует и его замена и т. д. Таким образом, это не 100% черно-белое.

Пожалуйста, дайте как можно больше возможных решений, как это возможно :)

Ну, что бы взять весь день .... :-P

+0

+1 для «книжного» ответа, который стоит прочитать. – AoeAoe

+0

@ Тони Делрой Спасибо тонну. – Thunderman

0

Первое, что я хотел бы сделать, это спросить "Сколько?" - насколько он слишком велик? Насколько он слишком медленный? Вторая вещь, которую я изучил, - это то, что (если что-либо) уже было сделано для оптимизации кода для достижения целей.

С одной стороны, если ничего не сделано, чтобы поразить цели, а вы закончились на пару процентов, скорее всего, довольно неплохая работа над флагов компилятора для выполнения задания. Если ваш код достаточно портативен, другой возможностью было бы просто использовать другой компилятор (например, если вы разрабатываете для Windows с помощью компилятора Microsoft, вероятность того, что вы можете получить несколько процентов как по размеру, так и по скорости, просто переключившись компилятору Intel).

С другой стороны, если вы слишком велики в 15 раз, слишком медленно, в 10 раз, и уже было довольно много работы, поставленной в оптимизацию, чтобы попытаться приблизиться к целям, вполне возможно, что цели просто не достижимы, и вам необходимо договориться с клиентом об изменении цели - удалении некоторых функций с использованием целевой системы, которая быстрее и имеет больше хранилища и т. д. Простой факт заключается в том, что если что-то не было сделано действительно плохо начать, у вас не так много шансов одновременно сделать код в 15 раз меньше и в 10 раз быстрее, сохранив те же функции.

Я бы добавил, что вы должны обычно обеспечить против последней ситуации с самого начала. Если вы ориентируетесь на систему с достаточно жесткими ограничениями на ОЗУ, скоростью процессора и т. Д., Вы обычно хотите сэкономить их с самого начала. Если вы закончите с бюджетом, который говорит, что вам нужно сделать БПФ на миллион точек данных, используя только 10 КБ ОЗУ и все еще закончив за 1 наносекунду, вам, вероятно, не нужно вообще писать какой-либо код, чтобы понять, что это просто не произойдет. Если размер и скорость важны, вы никогда не должны доходить до конечного продукта, который плохо выходит из-под контроля с требованиями.

Конечно, возможно перемещение цели - если вы сначала что-то разработаете для настольной машины, но в конце клиент говорит что-то вроде: «Ой, мы оставили там слово - мы имели в виду Windows Телефон 7 ". Опять же, вам придется говорить о приоритетах, хотя в этом случае речь может идти о том, можете ли вы перенести дату корабля и начать разработку с (ближе) к началу.

Смежные вопросы