__builtin_prefetch, сколько он читает? - PullRequest
15 голосов
/ 11 декабря 2011

Я пытаюсь оптимизировать C ++ ( RK4 ) с помощью

__builtin_prefetch

Я не могу понять, как предварительно выбрать всю структуру.

Я не понимаю, сколько из const void *addr прочитано. Я хочу загрузить следующие значения from и to.

for (int i = from; i < to; i++)
{
    double kv = myLinks[i].kv;
    particle* from = con[i].Pfrom;
    particle* to = con[i].Pto;
    //Prefetch values at con[i++].Pfrom & con[i].Pto;
    double pos = to->px- from->px;
    double delta = from->r + to->r - pos;
    double k1 = axcel(kv, delta, from->mass) * dt; //axcel is an inlined function
    double k2 = axcel(kv, delta + 0.5 * k1, from->mass) * dt;
    double k3 = axcel(kv, delta + 0.5 * k2, from->mass) * dt;
    double k4 = axcel(kv, delta + k3, from->mass) * dt;
    #define likely(x)       __builtin_expect((x),1)
    if (likely(!from->bc))
    {
            from->x += (( k1 + 2 * k2 + 2 * k3 + k4) / 6);
    }
}

Ссылка: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/

Ответы [ 2 ]

21 голосов
/ 11 декабря 2011

Я думаю, что он просто генерирует одну FETCH машинную инструкцию, которая в основном выбирает строковый кеш, размер которого зависит от процессора.

И вы можете использовать, например, __builtin_prefetch (con[i+3].Pfrom). По моему (небольшому) опыту, в таком цикле лучше заранее выбрать несколько элементов.

Не используйте __builtin_prefetch слишком часто (т. Е. Не помещайте их много в цикл). Измерьте прирост производительности, если он вам нужен, и используйте оптимизацию GCC (не менее -O2). Если вам очень повезет, ручное управление __builtin_prefetch может увеличить производительность вашего цикла на 10 или 20% (но это также может повредить).

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

Используйте также недавний компилятор GCC (последний выпуск - 4.6.2 ), потому что он делает большой прогресс в этих областях.


(добавлено в январе 2018 года:)

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

12 голосов
/ 11 декабря 2011

Читает строку кэша. Размер строки кэша может варьироваться, но, скорее всего, на современных процессорах он будет 64 байта. Если вам нужно прочитать несколько строк кэша, проверьте prefetch_range.

...