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
+1 для правила 90-20 ??? :) –
Очень интересно услышать правило 90-20. Для получения дополнительной информации: http://en.wikipedia.org/wiki/Pareto_principle –