Я думаю, что вы мало что можете сделать, что имеет большое значение. Может быть, вы можете немного ускорить его с помощью OpenMP или SSE. Но современные процессоры уже довольно быстрые. В некоторых приложениях пропускная способность / задержка памяти на самом деле является узким местом, и оно ухудшается. У нас уже есть три уровня кеша, и нам нужны интеллектуальные алгоритмы предварительной выборки, чтобы избежать огромных задержек. Поэтому имеет смысл подумать и о шаблонах доступа к памяти. Например, если вы реализуете такие multiply
и add
и используете их так:
void multiply(float vec[], float factor, int size)
{
for (int i=0; i<size; ++i)
vec[i] *= factor;
}
void add(float vec[], float summand, int size)
{
for (int i=0; i<size; ++i)
vec[i] += summand;
}
void foo(float vec[], int size)
{
multiply(vec,2.f,size);
add(vec,9.f,size);
}
вы в основном дважды проходите через блок памяти. В зависимости от размера вектора он может не помещаться в кэш L1, и в этом случае его повторное прохождение дважды добавляет дополнительное время. Это явно плохо, и вы должны стараться, чтобы доступ к памяти был «локальным». В этом случае один цикл
void foo(float vec[], int size)
{
for (int i=0; i<size; ++i) {
vec[i] = vec[i]*2+9;
}
}
скорее всего будет быстрее. Как правило: попробуйте получить доступ к памяти линейно и попытаться получить доступ к памяти «локально», что я имею в виду, попробуйте повторно использовать данные, которые уже находятся в кэше L1. Просто идея.