Я работаю над проблемой, когда хочу собрать временные ряды, записанные в разных местах, и извлечь когерентный сигнал. Поднятие тяжестей выполняется в C с помощью оболочки Python для обеспечения более дружественного интерфейса. Я достиг точки, когда я удовлетворен теоретической правильностью алгоритма и хотел бы максимально оптимизировать его. Я достаточно понимаю C, чтобы написать что-то, что работает и распараллеливается с openMP, но не намного дальше этого.
Оптимизация проблемы важна, так как я имею дело с большими наборами данных - до 200 временных рядов в стеке частота дискретизации до 1000 Гц, порядок записи от нескольких месяцев до нескольких лет. Обработка может длиться от нескольких дней до нескольких недель с разумными вычислительными возможностями. Я выполняю этот шаг стекирования на кусках непрерывного временного ряда, чтобы не забивать память.
У меня есть несколько вопросов:
Есть ли что-то очевидное, что мне не хватает что поможет (оптимизация с помощью компилятора, оптимизация алгоритма)?
Самый значительный выигрыш, достигнутый к настоящему времени, был достигнут с флагом оптимизации -Ofast - я прочитал и просто хотел понять немного больше почему это быстрее и является ли это "безопасным" для моих целей?
Куда (помимо траления через SO) я должен обратиться, чтобы узнать больше о такого рода проблемы? У меня есть другие проблемы в моем исследовании, которые я бы хотел решить, используя C!
Алгоритм
Я собираю временные ряды из каждого места непрерывно во времени в трехмерном сетчатом объеме. После того, как полный стек закончен для данной ячейки, мне нужно возвести в степень результат и нормализовать по количеству участвующих временных рядов.
#define MAX(a,b) (((a)>(b))?(a):(b))
EXPORT void migrate(double *sigPt, int32_t *indPt, double *mapPt, int32_t fsmp, int32_t lsmp, int32_t nsamp, int32_t nstation, int32_t avail, int64_t ncell, int64_t threads)
{
double *stnPt, *stkPt, *eStkPt;
int32_t *ttpPt;
int32_t ttp;
int32_t to, tm, st;
int64_t cell;
#pragma omp parallel for private(cell,stkPt,eStkPt,ttpPt,st,ttp,tm) num_threads(threads)
for (cell=0; cell<ncell; cell++)
{
stkPt = &mapPt[cell * (int64_t) nsamp];
eStkPt = &mapPt[cell * (int64_t) nsamp];
ttpPt = &indPt[cell * (int64_t) nstation];
for(st=0; st<nstation; st++)
{
ttp = MAX(0,ttpPt[st]);
stnPt = &sigPt[st*(fsmp + lsmp + nsamp) + ttp + fsmp];
for(tm=0; tm<nsamp; tm++)
{
stkPt[tm] += stnPt[tm];
}
}
for(tm=0; tm<nsamp; tm++)
{
eStkPt[tm] = exp(stkPt[tm] / avail);
}
}
}
В настоящее время я компилирую с:
gcc -shared -fPIC -std=gnu99 ./source.c -fopenmp -Ofast -lm -o ./output
Я прочитал:
Профилирование python C расширения
Какие флаги и методы оптимизации G CC безопасны для разных процессоров?
среди прочих. Извинения, если я повторяю вопрос / мой вопрос плохо определен.