Я недавно обновил наш производственный код нейронной сети до AVX-512; это определенно реальный производственный код. Ключевой частью наших оптимизаций является то, что каждая матрица не a std::vector
, а 1D-выровненный массив AVX. Даже без выравнивания AVX мы видим огромное преимущество в переходе к одномерному массиву, поддерживающему каждую матрицу. Это означает, что доступ к памяти будет полностью последовательным, что намного быстрее. Размер тогда будет (rows*cols)*sizeof(float)
.
Мы сохраняем смещение как первый полный ряд. Обычно это реализуется с помощью префикса ввода элементом 1.0
, но для нашего кода AVX мы используем смещение в качестве начальных значений для операций FMA (Fused Multiply-Add). Т.е. в псевдокоде result=bias; for(input:inputs) result+=(input*weight)
. Это сохраняет вход также AVX-выровненным.
Поскольку каждая матрица используется по очереди, вы можете безопасно иметь std::vector<Matrix> layers
.