2016-11-05 2 views
0

У меня есть низкоуровневая функция, которая будет называться миллионы раз, поэтому она должна быть очень эффективной. Когда я использую «gprof» в Linux, я обнаружил, что часть кода занимает 60% от общего вычисления функции (остальная часть - для решения корней кубического уравнения). Здесь Point - структура данных имеет x и v, которые будут преобразованы в матрицу для последующего использования. Идея состоит в том, чтобы вычесть каждую строку по первой строке. Код показан нижеКак улучшить производительность массива 2d в C++

double x[4][3] = {0}, v[4][3] = {0}; 
    for (int i = 0; i < 4; ++i){ 
     for (int j = 0; j < 3; ++j){ 
      v[i][j] = Point[i]->v[j]; 
      x[i][j] = Point[i]->x[j]; 
     } 
    } 
    for (int i = 1; i < 4; ++i){ 
     for (int j = 0; j < 3; ++j){ 
      v[i][j] = v[0][j] - v[i][j]; 
      x[i][j] = x[0][j] - x[i][j]; 
     } 
    } 

Может ли кто-нибудь показать мне проблему с этим кодом? Почему это так плохо?

+1

Если ваш код работает, но может использовать улучшение, это не по теме здесь. Пожалуйста, опубликуйте его на Code Review. – Carcigenicate

+1

Вы позволили компилятору сделать все возможное, установив уровень оптимизации 3 или аналогичный? –

+0

Что такое 'Point'? –

ответ

0

Вы можете сделать все это за один проход:

double x[4][3] = { 
    { Point[0]->x[0], Point[0]->x[1], Point[0]->x[2] } 
}; 
double v[4][3] = { 
    { Point[0]->v[0], Point[0]->v[1], Point[0]->v[2] } 
}; 

for (int i = 1; i < 4; ++i){ 
    for (int j = 0; j < 3; ++j){ 
     x[i][j] = x[0][j] - Point[i]->x[j]; 
     v[i][j] = v[0][j] - Point[i]->v[j]; 
    } 
} 

Можно даже считать, что на следующий уровень и положить все вещи в инициализаторах для x и v.

Или, если x и v в Point являются каждыми смежными массивами:

double x[4][3], v[4][3]; // no init 

// fill entire arrays 
for (int i = 0; i < 4; ++i){ 
    memcpy(x[0], Point[0]->x, sizeof(x[0])); 
    memcpy(v[0], Point[0]->v, sizeof(v[0])); 
} 

for (int i = 1; i < 4; ++i){ 
    for (int j = 0; j < 3; ++j){ 
     x[i][j] -= Point[i]->x[j]; 
     v[i][j] -= Point[i]->v[j]; 
    } 
} 
+0

Я изменил, как вы предполагали, но это не решило проблему. Интересно видеть, что функция «memcpy» даже занимает больше времени, чем вручную присваивает значения. Развертывание двойного цикла также дает некоторые улучшения в производительности. Из-за этого это принесет жертву читабельности. –

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