Оптимизация цикла C с помощью условных обозначений для переменной цикла

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

Дистиллированная версия проблемы, над которой я работаю, выглядит следующим образом. Мне нужно выполнить ряд вычислений, которые сохранят значения в 4 (очень больших) массивах: A, B, C и D. Эти вычисления взаимозависимы, например, для вычисления b [i] может потребоваться использование a [i-1]. Я могу выразить все в одном цикле, но это приводит к крайним случаям, когда для определенных значений i должны выполняться только некоторые вычисления. Например:

for(i=0;i<end;i++)
{
    if(i == 0)
        //calculate A[i+1] and B[i+1]
    else if (i == end-1)
        //calculate C[i-1] and D[i-1]
    else
        //calculate A[i+1], B[i+1], C[i-1], D[i-1]
}

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

//calculate A[1] and B[1]
for(i=1;i<end-1;i++)
{
    //calculate A[i+1], B[i+1], C[i-1], D[i-1]
}
//calculate C[end-2] and D[end-2]

. Я понял из архивов, что компилятор разорвал бы мой цикл, если бы условные выражения были постоянными, но здесь они зависят от i, что в принципе могло бы ] быть измененным некоторыми моими расчетами. Сможет ли он обнаружить, что я не вмешиваюсь в переменную итерации, и, таким образом, разбить ее на части разумным образом?

Дополнительная информация, если вы решите ответить на вопрос, предложив лучший способ сделать что-то:

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

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

Заранее спасибо!

10
задан Ben 12 July 2011 в 22:22
поделиться