Estou pensando em acelerar os produtos vetoriais de matriz, mas tudo o que leio é sobre como fazer isso para matrizes muito grandes. No meu caso, as matrizes são pequenas, mas o número de vezes que isso deve ser feito é muito grande.
Quais métodos, se houver, existem para otimizar isso? Seria mais rápido construir uma matriz de blocos diagonal realmente grande a partir das matrizes pequenas e um vetor grande composto por vetores menores e usar as técnicas para as grandes acelerações de vetores matriciais? Ou a criação da matriz global e do vetor mataria algum benefício lá?
linear-algebra
optimization
tpg2114
fonte
fonte
Respostas:
Antes de tentar otimizar seu código, vale a pena perguntar se há algo para otimizar, para começar. As bibliotecas que otimizam os produtos vetoriais matriciais o solucionam dois problemas: limitações no tamanho do cache e na latência para carregar dados da memória. O primeiro é feito usando os dados que estão atualmente no cache em sua extensão máxima para tudo o que ele precisa ser usado antes de substituí-lo por outros dados; o último é feito pré-buscando dados no cache antes de realmente usá-lo.
No seu caso, você tem relativamente pouca intensidade aritmética de seus dados - você carrega dados da memória, usa-os exatamente uma vez e depois passa para a próxima matriz. Isso deixa apenas o segundo caminho para otimizar: pré-buscar dados antes de usá-los.
Mas, como eu disse, antes de tentar otimizar as coisas, pode valer a pena descobrir o que você já tem: tempo quantos produtos vetoriais de matriz você está fazendo por segundo, calcule quantos bytes isso requer para carregar da memória no seu processador, e compare isso com a largura de banda do processador que você possui na sua máquina. Você pode achar que não há nada que possa fazer para tornar as coisas mais rápidas.
fonte
Ele não pode realmente importa desde suas matrizes são cache já contido, mas você deve estar chamando
dgemv()
ousgemv()
o equivalente da melhor biblioteca BLAS você pode chegar em suas mãos. Você deve experimentar o Intel MKL se puder obter acesso a ele, e também o BLIS ou ATLAS ou uma das muitas outras bibliotecas otimizadas do BLAS disponíveis no mercado.fonte
Gerar código C ++ e usar Eigen / Armadillo é uma possibilidade, mas isso depende do aplicativo.
A solução para nós foi apenas escrever o resultado explicitamente para . Sem os loops, o código é muito rápido com compiladores modernos e suporte a vetores (sse2, avx2 e avx512 em 64 bits).N<8
Cuide do alinhamento da memória dos seus dados (até 64 bytes alinhados) e restrinja os ponteiros para facilitar a vida do compilador. Não é necessário usar o suporte multicore com esses tamanhos de matriz, a sobrecarga é maior que o ganho.
Usamos scripts para gerar automaticamente funções separadas para cada combinação possível e armazenar em cache os ponteiros de função para chamadas consecutivas.
Existe uma biblioteca barata e agradável para operações de matriz pequena que é altamente otimizada manualmente, chamada OptiVec , e funciona muito bem no nosso caso. Nós o usamos para .N≥8
fonte