2015-11-19 1 views
2

Центральная функция в моем коде выглядит следующим образом (все остальное поступает ваниль и выход):Как я могу скомпилировать этот очень большой, но скучный источник C?

const int n = 40000; 

double * foo (double const * const x) 
{ 
    double * y = malloc (n*sizeof(double)); 

    y[0] = x[0] + (0.2*x[1]*x[0] - x[2]*x[2]); 
    y[1] = x[1] + (0.2*x[1]*x[0] - x[2]*x[2]); 
    // … 
    // 39997 lines of similar code 
    // that cannot be simplified to fewer lines 
    // … 
    y[40000] = 0.5*x[40000] - x[12345] + 5*x[0]; 

    return y; 
} 

Предположим, для целей данного вопроса, что жесткое кодирование этих 40000 строк, как это (или очень похоже) является действительно необходимо. Все эти строки содержат только основные арифметические операции с фиксированными числами и записями x (сорок на строку в среднем); никакие функции не вызываются. Общий размер источника составляет 14 МБ.

При попытке скомпилировать этот код я сталкиваюсь с обширным использованием памяти компилятором. Я мог бы заставить Clang скомпилировать его с -O0 (который занимает всего 20 секунд), но я потерпел неудачу с GCC (даже с -O0) или с -O1.

Хотя мало что можно оптимизировать на стороне кода или в глобальном масштабе (т. Е. Вычисляя отдельные строки в другом порядке), я уверен, что компилятор найдет некоторые вещи для оптимизации в локальном масштабе (например, вычисление заключенного в квадратные скобки срока, необходимого для расчета y[0] и y[1]).

Моих вопросы таким образом:

  • Есть некоторые флаги компилятора, которые активизируют только оптимизации, которые не требуют много дополнительной памяти?
  • Есть ли другие способы заставить компилятор обрабатывать этот источник лучше (без потери большей скорости, чем при оптимизации)?
+0

Примечание: Любая причина, по которой вы делаете 'x'' const', но не массив, на который он указывает? – Olaf

+4

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

+0

разбить его на 4 файла по 10000 строк каждый? –

ответ

1

The following comment Ли Даниэль Крокер решил проблему:

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

При использовании функции 100 строк каждого (и вызова все из них в строке), я получил программу, я мог компилировать с -O2 без каких-либо проблем.

+0

Я не вижу, как это отвечает на вопрос, учитывая исходный вопрос, содержащий следующее утверждение. Предположим, что для этого вопроса жесткое кодирование этих 40000 строк, подобных этому (или очень похожего), действительно необходимо. Все эти строки содержат только основные арифметические операции с фиксированными числами и элементами x (сорок на каждую строку в среднем); никакие функции не вызываются. –

-1

Запишите его в сборке.

Я предполагаю, что у вас есть инструмент, который генерирует этот файл C. Почему бы им не выплюнуть ассемблерный код?

+1

Помимо изучения уроков, это, вероятно, не принесет никаких преимуществ в оптимизации. – Wrzlprmft

+0

Возможно, вы могли бы создать clang для сборки и выполнить оптимизацию, а затем связать ее с остальной частью вашего проекта, который использует GCC. –

+0

Написание пользовательской сборки (если выполнено правильно) принесет огромные преимущества по оптимизации. – user3386109

0

Вы можете add swap space столько, сколько требуется, чтобы заставить компилятор компилировать код с включенными оптимизациями. Используя этот метод, процесс компиляции станет намного медленнее. Однако объем памяти, доступный компилятору, будет ограничен только размером виртуального адресного пространства. Другим менее удобным вариантом является установка большего количества оперативной памяти. Также убедитесь, что процесс, в котором выполняется компилятор, не имеет ограничений на объем памяти, который он может выделить. Что касается флагов компилятора, я не думаю, что есть флаги, которые вы можете использовать для прямого управления использованием памяти компилятором и позволить компилятору приспособиться к указанному пределу.

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