Подсказки компилятора g++ для размещения в стеке

Существуют ли какие-либо методы, чтобы дать подсказке компилятору, что некоторые объекты могут иметь более статичное поведение, и размещать вещи в стеке вместо кучи? Например, строковый объект может иметь вид постоянного размера внутри некоторых функций. Я спрашиваю об этом, потому что я пытаюсь улучшить производительность приложения с помощью OpenMP. Я уже улучшил последовательную часть с 50 до 20 секунд, и она идет до 12 секунд с параллелизмом (упомянув, что большая часть кода может выполняться параллельно). Я пытаюсь продолжить улучшение. Я думаю, что одно ограничение связано с непрерывным выделением и освобождением динамической памяти внутри одного и того же процесса. До сих пор последовательная оптимизация была связана со слиянием с более ANSI C-подходом с более жестко заданным распределением переменных (они распределяются динамически, но с учетом наихудшего сценария, поэтому все распределяется один раз). Теперь я в значительной степени застрял, потому что я достиг части кода, которая имеет большой подход C++.

3 ответа

Стандартный шаблон std::basic_string (из которых std::string является специализацией) принимает распределитель в качестве третьего аргумента, и вы могли бы предоставить свой собственный распределитель на основе стека вместо std:: allocator, но это было бы хрупко и хитро (вы могли бы использовать alloca(3) и убедиться, что все выделения встроены, если они не alloca не будет работать, как вы хотите.). Я не рекомендую этот подход.

Более жизнеспособным подходом может быть наличие собственной арены или распределителя на основе региона. Смотрите std::allocator_traits

Вы могли бы просто использовать C snprintf (3) на достаточно большом локальном буфере (например, char buf[128];)

Итак, вы ищете недостатки, используя статический анализ, чтобы найти регрессии производительности?

Это хорошая идея, у cppcheck есть некоторые из них, но они очень элементарные. Я не знаю ни одного инструмента, который делает это до сих пор.

Однако существуют инструменты, которые делают разные вещи:

jemalloc

jemalloc имеет профилировщик распределения. (См.: http://www.canonware.com/jemalloc/) Возможно, это вам поможет. Я сам не пробовал это делать, но я ожидал, что он опубликует время жизни объектов и объектов, которые оказывают наибольшее давление на распределитель (чтобы сначала найти наиболее болезненные части).

похожем на Cachegrind

Valgrind также имеет симулятор кеша и предсказания ветвлений. http://valgrind.org/docs/manual/cg-manual.html

лязг проверка

если у вас слишком много свободного времени, вы можете попробовать запустить свои собственные инструменты проверки, используя clang-check,

Google Perftools

Инструменты Google Perf также имеют профилировщик кучи. https://code.google.com/p/gperftools/

Я думаю, что вы ищете небольшую буферную оптимизацию. Подробное описание можно найти здесь. Основная идея состоит в том, чтобы добавить объединение в класс, который будет содержать буфер:

class string
{
  union Buffer
  {
    char*    _begin;
    char[16] _local;
  };

  Buffer _buffer;
  size_t _size;
  size_t _capacity;
  // ...
};
Другие вопросы по тегам