SHA256 l'optimisation de la performance en C
J'ai besoin de hachage une grande base de données de valeurs assez souvent. Ainsi, une mise en œuvre rapide d'un SHA-2 hasher est nécessaire. Je suis actuellement en utilisant le SHA256.
La sha256_transform algorithme que j'utilise pour l'instant:
http://bradconte.com/sha256_c
(code ci-dessous)
J'ai profilé mon code et cet extrait est de prendre exactement 96% de temps de calcul par hachage, faisant de cette fonction essentielle à mes objectifs.
Il fonctionne sur 64 octets chaîne binaire nommé data[]
et renvoie le résultat dans ctx->state
.
Je demande pour une version plus rapide de cette fonction. Gardez à l'esprit que même avec de légères modifications peuvent vitesse d'impact négatif.
#define uchar unsigned char
#define uint unsigned int
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
void sha256_transform(SHA256_CTX *ctx, uchar data[]) {
uint a,b,c,d,e,f,g,h,i,j,t1,t2,m[64];
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];
for (i=0,j=0; i < 16; i++, j += 4)
m[i] = (data[j] << 24) | (data[j+1] << 16) | (data[j+2] << 8) | (data[j+3]);
for ( ; i < 64; i++)
m[i] = SIG1(m[i-2]) + m[i-7] + SIG0(m[i-15]) + m[i-16];
for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}
- Si vous êtes heureux de limiter votre code x86 puis on dirait qu'il pourrait y avoir des opportunités pour les SIMD optimisation à l'aide de l'ESS/AVX2.
- Il prend 96% du temps, pas parce que c'est mal écrit, mais parce qu'il est intrinsèquement complexe. Cela a été optimisé assez bien, donc si vous avez besoin de passer moins de temps de calcul, chercher des façons d'appeler moins souvent.
- Est-il quelque chose de votre code actuel ne peut pas le faire dès maintenant, parce que le présent est de prendre votre CPU thermal de nouvelles hauteurs?
- +1 pour le sens commun. Sinon, je sais que le multithreading est un must-have ici, mais il n'est pas le point de la question. En fait oui, je pose la question parce que à la fois la vitesse ET la surchauffe du processeur.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez checkout/profil de cette mise en place de SHA256.
Être utilisé dans cgminer (populaire bitcoin mining logiciel), il est écrit spécifiquement de maintien de la performance à l'esprit. Il comprend 4-way SIMD implémentations utilisant SSE2. Il suit la même approche que la bradconte sha256_transform algorithme mentionné dans la question. Le code est trop long de reproduire ici.
Également la licence est assez permissive, permettant de ré-utilisation, de distribution, tant que les auteurs originaux sont accrédités.
4-way SIMD implementations using SSE2
que vous êtes, de mentionner?Maintenant que le Goldmont micro-architecture a été libéré, il intègre un processeur Intel de SHA extensions. Vous pouvez obtenir un 5x-6x speedup dans le compresser fonction à l'aide des instructions du PROCESSEUR. Par exemple, code proposé pour une bibliothèque crypto assisté à la suivante (le test s'est produite sur une Celeron J3455, qui fonctionne à 1,5 GHz, mais des rafales à 2,3 GHz):
Voici le code pour le SHA256 compresser à l'aide de la fonction Intel SHA extensions avec intrinsèques. Il est basé sur Sean Gulley sur son blog Intel® SHA Extensions, et son exemple de code dans mitls | hacl-star | expérimental.
La
compress
fonction ci-dessous ne gère plein de blocs de 64 octets. Vous avez besoin pour l'installation de l'état initial, et vous avez besoin pour compléter le dernier bloc. On dirait que vous avez abordés dans votre exemple de code.Vous pouvez trouver à la source pour les processeurs Intel SHA intrinsèques et ARMv8 SHA intrinsèques à Noloader GitHub | SHA-Intrinsèques. Ils sont des fichiers source C, et de fournir les compresser fonction pour SHA-1, SHA-224 et SHA-256. La valeur intrinsèque en fonction des implémentations d'augmenter le débit d'environ 3x 4x pour SHA-1, et d'environ 6x de 12x pour SHA-224 et SHA-256.
C'est la référence Intel de mise en œuvre:
http://downloadmirror.intel.com/22357/eng/sha256_code_release_v2.zip
Et le code est décrit dans:
http://www.intel.com/content/www/us/en/intelligent-systems/intel-technology/sha-256-implementations-paper.html
Je reçois environ 350 MO/s sur un haswell base de Xeon microprocesseur (E5-2650 v3). Il est mis en œuvre dans l'assemblée et prend avantage de la technologie Intel ® AES-NI.
Mise à jour:
Les derniers processeurs Intel de référence de mise en œuvre de SHA (qui fait maintenant partie de l'ISA-L_crypto) est situé à:
https://github.com/01org/isa-l_crypto/tree/master/sha256_mb
AVX
,AVX2
etSSE4
. Au lieu de cela, Intel est le code qui utiliseSHA256RNDS2
,SHA256MSG1
etSHA256MSG2
instructions (oui, trois SHA256-instructions spéciales) sont beaucoup plus rapide, et peut être trouvé ici: software.intel.com/en-us/articles/... N'oubliez pas de__get_cpuid(7, &eax, &ebx, &ecx, &edx) && (ebx >> 29) & 1)
Vérifier la mise en œuvre du Dr Brian Gladman - http://www.gladman.me.uk/. Son environ 15% plus rapide que celui de cgminer. Je ne pense pas que vous pouvez faire beaucoup mieux sans l'aide de l'ESS