Qual é a velocidade-up máxima teórica devido à SSE para uma subtração binária simples?
-
13-09-2019 - |
Pergunta
Na tentativa de descobrir se ou não loop interno do meu código está batendo uma barreira design de hardware ou de uma falta de compreensão sobre a minha barreira parte. Há um pouco mais do que isso, mas a questão mais simples que posso vir acima com a resposta é a seguinte:
Se eu tenho o seguinte código:
float px[32768],py[32768],pz[32768];
float xref, yref, zref, deltax, deltay, deltaz;
initialize_with_random(px);
initialize_with_random(py);
initialize_with_random(pz);
for(i=0;i<32768-1;i++) {
xref=px[i];
yref=py[i];
zref=pz[i];
for(j=0;j<32768-1;j++ {
deltx=xref-px[j];
delty=yref-py[j];
deltz=zref-pz[j];
} }
Que tipo de velocidade máxima teórica se eu seria capaz de ver, indo para instruções SSE em uma situação onde eu tenho o controle completo sobre o código (montagem, intrínsecos, qualquer que seja), mas nenhum controle sobre o ambiente de tempo de execução diferente de arquitetura (ou seja, é um ambiente multi-usuário, então não posso fazer nada sobre como o cessionários de kernel oS tempo para o meu processo particular).
Agora eu estou vendo uma velocidade até de 3x com meu código, quando eu teria pensado usando SSE me daria muito mais profundidade do que o vector 3x velocidade até está indicando (presumivelmente o 3x velocidade até me diz que eu tenho um máxima 4x rendimento teórico). (Eu tentei coisas como deixar deltx / delty / deltz ser matrizes no caso o compilador não foi suficiente inteligente para auto-promover-los, mas eu ainda ver apenas 3x acelerar.) Eu estou usando o compilador Intel C com as bandeiras apropriadas do compilador para vetorização, mas não intrínsecos obviamente.
Solução
Depende da CPU. Mas o máximo teórico não vai ficar acima de 4x. Eu não sei de uma CPU que pode executar mais de uma instrução SSE por ciclo de clock, o que significa que ele pode , no máximo, de computação 4 valores por ciclo.
A maioria CPU pode fazer , pelo menos um flutuante instrução escalar ponto por ciclo, por isso, neste caso, você veria um máximo teórico de uma 4x aceleração.
Mas você vai ter que olhar para cima a instrução específica de transferência para a CPU que está sendo executado.
A aceleração prática de 3x é bom muito embora.
Outras dicas
Eu acho que você provavelmente teria que intercalam o loop interno de alguma forma. O vetor de 3 componentes está sendo feito de uma só vez, mas isso é apenas 3 operações ao mesmo tempo. Para chegar a 4, você faria 3 componentes do primeiro vector, e 1 a partir da próxima, em seguida, 2 e 2, e assim por diante. Se você estabeleceu algum tipo de fila que carrega e processa os dados 4 componentes de cada vez, então separá-lo depois, que o trabalho poder.
Editar: Pode-se desenrole o loop interno para fazer 4 vectores por iteração (assumindo que o tamanho da matriz é sempre um múltiplo de 4). Isso iria realizar o que eu disse acima.
Considere: Qual a largura um float? Quão grande é a instrução SSEx? A relação deve deve dar-lhe algum tipo de razoável limite superior.
Também é importante notar que out-of-order tubos jogar havok com a obtenção de estimativas boas da aceleração.
Você deve considerar laço azulejos - do jeito que você está acessando valores no circuito interno é provavelmente causando muita surra no cache de dados L1. Não é muito ruim, porque tudo o que provavelmente ainda se encaixa na L2 em 384 KB, mas não é facilmente uma ordem de diferença de magnitude entre um acerto de cache L1 e um acerto de cache L2, assim que este poderia fazer uma grande diferença para você.