J'apprends maintenant SIMD et je pense à la façon de laisser le compilateur optimiser mon code. Maintenant, je joue avec Visual C++ 2013 x86.Comment faire pour que le compilateur VC optimise mon code avec SIMD?
J'ai un tableau, j'ai un autre tableau, et je veux calculer comme ceci:
void computeSum(float* __restrict arr, float* __restrict inp1, float* __restrict inp2, int count)
{
__declspec(align(16)) float* p1 = inp1;
__declspec(align(16)) float* p2 = inp2;
__declspec(align(16)) float* ret = arr;
while (count > 0)
{
ret[0] = p1[0] + p2[0];
ret[1] = p1[1] + p2[1];
ret[2] = p1[2] + p2[2];
ret[3] = p1[3] + p2[3];
p1 += 4;
p2 += 4;
ret += 4;
count -= 4;
}
}
Je veux dire au compilateur que les tableaux sont alignés à la limite et toute personne de 16 octets est recouvre pas sur une autre, et une boucle calculera la somme de 4 nombres de flottants continus.
Mais dans le code généré, VC préfère MOVSS/ADDSS et n'utilise pas ADDPS comme je l'espère.
Si je configure le projet d'utiliser la chaîne d'outils LLVM-vs2013, il utilise ADDPS pour calculer la somme.
Je sais comment utiliser les intrinsèques du compilateur pour écrire du code SIMD, mais ce n'est pas ce que je veux.
Y a-t-il d'autres indications que VC doit utiliser l'instruction ADDPS?
Ceci est la pleine pièce de code.
#include <stdio.h>
#include <stdlib.h>
void computeSum(float* __restrict arr, float* __restrict inp1, float* __restrict inp2, int count)
{
__declspec(align(16)) float* p1 = inp1;
__declspec(align(16)) float* p2 = inp2;
__declspec(align(16)) float* ret = arr;
while (count > 0)
{
ret[0] = p1[0] + p2[0];
ret[1] = p1[1] + p2[1];
ret[2] = p1[2] + p2[2];
ret[3] = p1[3] + p2[3];
p1 += 4;
p2 += 4;
ret += 4;
count -= 4;
}
}
int main()
{
float* inp1 = (float*)_aligned_malloc(sizeof(float) * 128, 16);
float* inp2 = (float*)_aligned_malloc(sizeof(float) * 128, 16);
float* result = (float*)_aligned_malloc(sizeof(float) * 128, 16);
for (int i = 0; i < 128; ++i)
{
inp1[i] = inp2[i] = i;
}
computeSum(result, inp1, inp2, 128);
for (int i = 0; i < 128; ++i)
{
printf("%f\t", result[i]);
}
return 0;
}
Avez-vous spécifié/arch: SSE (ou similaire)? – harold
@harold oui, le commutateur/arch: SSE2 est activé. – Sorayuki
Avez-vous essayé avec * non * le déroulement de la boucle? –