begin process at 2012 05 24 03:44:20
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Application Unix

 > PRODUIT SCALAIRE VIA INSTRUCTIONS SIMD (ASSEMBLEUR 80X86 64 BITS)

PRODUIT SCALAIRE VIA INSTRUCTIONS SIMD (ASSEMBLEUR 80X86 64 BITS)


 Information sur la source

Note :
Aucune note
Catégorie :Application Unix Classé sous :simd, pmul, gnu, gcc, 64 bits Niveau :Initié Date de création :01/10/2010 Vu / téléchargé :2 261 / 41

Auteur : pierrejourlin

Ecrire un message privé
Site perso
Commentaire sur cette source (0)
Ajouter un commentaire et/ou une note

 Description

Système : Distribution x86_64-linux-gnu
Procédure réalisant le produit scalaire de 2 matrices 4x4  d'entiers signés sur 16 bits. Le résultat de l'opération est une matrice 4x4 d'entiers signés sur 32 bits. Afin d'obtenir les meilleures performances en temps de calcul, nous utilisons les instructions SIMD (single instructions multiple data ; instruction unique à données multiples).

Source

  • .data # directive de création d'une zone de donnée
  • .align 8
  • m1: .word 0, 1, 2, 3
  • .word 4, 5, 6, 7
  • .word 8, 9, 10, 11
  • .word 12, 13, 14, 15
  • m2: .word 0, 4, 8, 12
  • .word 1, 5, 9, 13
  • .word 2, 6, 10, 14
  • .word 3, 7, 11, 15
  • m3: .long 0, 0, 0, 0
  • .long 0, 0, 0, 0
  • .long 0, 0, 0, 0
  • .long 0, 0, 0, 0
  • FormatString16: # pour les appels à printf
  • .string " %.3d"
  • FormatString32: # pour les appels à printf
  • .string " %.6ld"
  • RetourChariot:
  • .string "\n"
  • Annoncem1:
  • .string "matrice m1:\n"
  • Annoncem2:
  • .string "matrice m2:\n"
  • Annoncem22:
  • .string "matrice m2 pivotée:\n"
  • Annoncem3:
  • .string "m1 x m2 = \n"
  • .text # directive de création d'une zone d'instructions
  • .globl main # directive de création d'une étiquette
  • main: # main est l'adresse de début du programme
  • pushq $Annoncem1
  • call AfficheChaineSimple
  • pushq $m1
  • call AfficheMatrice16 # Affiche la première matrice
  • pushq $Annoncem2
  • call AfficheChaineSimple
  • pushq $m2
  • call AfficheMatrice16 # Affiche la deuxième matrice
  • pushq $m1
  • pushq $m2
  • pushq $m3
  • call ProduitScalaire
  • pushq $Annoncem22
  • call AfficheChaineSimple
  • pushq $m2
  • call AfficheMatrice16 # Affiche la deuxième matrice après
  • # inversion ligne/colonnes
  • pushq $Annoncem3
  • call AfficheChaineSimple
  • pushq $m3
  • call AfficheMatrice32 # Affiche la matrice résultat
  • movq $1,%rax # sélection de la fonction exit
  • # du système
  • xorq %rbx,%rbx # mise à zéro du 1er paramètre en
  • # utilisant xor, c'est à dire ou exclusif
  • int $0x80 # appel de l'interruption
  • # 128 -> GNU/Linux
  • fin: ret
  • ProduitScalaire:
  • movq 16(%rsp), %rdi # adresse de la deuxième matrice
  • pushq %rdi # pivote la 2e matrice pour avoir les
  • # vecteurs colonnes
  • call Pivote # en lignes
  • movq 8(%rsp), %rcx # adresse de la matrice produit
  • movq 16(%rsp), %rdi # adresse de la deuxième matrice
  • movq 24(%rsp), %rsi # adresse de la première matrice
  • movq $0, %rax # indice de la ligne de la première
  • # matrice
  • TraiteLigne:
  • movq $0, %rbx # indice de la ligne de la transposée
  • # de la seconde matrice
  • TraiteColonne:
  • movq (%rsi, %rax, 8), %mm0 # charge la ligne de la 1ere
  • # matrice dans mm0
  • movq (%rdi, %rbx, 8), %mm1 # charge la colonne de la 2e
  • # matrice (ou ligne de sa
  • # transposée) dans mm1
  • pmullw %mm1, %mm0 # %mm0 : partie basse du produit
  • # composante par composante
  • call SommeDesComposantes # rdx contient la somme des
  • # composantes 8 bits de %mm0
  • movw %dx, (%rcx) # copie du résultat dans la
  • # matrice produit
  • movq (%rsi, %rax, 8), %mm0 # charge la ligne de la 1ere
  • # matrice dans mm0
  • pmulhw %mm1, %mm0 # %mm0 : partie haute du produit
  • # composante par composante
  • call SommeDesComposantes # rdx contient la somme des
  • # composantes 8 bits de %mm0
  • shll $16, %edx # décale le résultat de 16 bits vers la
  • # gauche pour le mettre en partie haute
  • addl %edx, (%rcx) # ajoute la partie haute du résultat dans
  • # la matrice produit
  • addq $4, %rcx # pointe sur l'élément suivant à calculer
  • addq $1, %rbx # indice de colonne suivant
  • cmpq $4, %rbx # fin de colonne ?
  • jne TraiteColonne
  • movq $0, %rbx # on recommence à la colonne 0
  • addq $1, %rax # ligne suivante
  • cmpq $4, %rax # dernière ligne ?
  • jne TraiteLigne
  • ret $24
  • Pivote: movq 8(%rsp), %rsi # adresse de la matrice à pivoter
  • movq $0, %rax # indice de ligne (l)
  • movq $0, %rbx # indice de colonne (c)
  • TraiteElement:
  • cmpq %rax, %rbx
  • jbe ColSuivante # élément suivant si l<=c
  • movq %rsi, %rdi # on va échanger l'élément (l,c)
  • # avec l'élément (c,l)
  • addq %rax, %rdi
  • addq %rax, %rdi # rdi:base + l * 2
  • pushw (%rdi, %rbx, 8) # élément (l,c) -> pile
  • movq %rsi, %rdx
  • addq %rbx, %rdx
  • addq %rbx, %rdx # rdx:base + c*2
  • pushw (%rdx, %rax, 8) # élément (c,l) -> pile
  • popw %cx
  • movw %cx, (%rdi, %rbx, 8)# pile -> élément (l, c)
  • popw %cx
  • movw %cx, (%rdx, %rax, 8)# pile -> element (c ,l)
  • ColSuivante:
  • addq $1, %rbx
  • cmpq $4, %rbx
  • jne TraiteElement
  • movq $0, %rbx # retour à la colonne 0
  • addq $1, %rax # ligne suivante
  • cmpq $4, %rax
  • jne TraiteElement
  • ret $8
  • SommeDesComposantes:
  • pushq %rax # sauvegarde
  • pushq %rbx # sauvegarde
  • pushq %rcx # sauvegarde
  • movq $0, %rdx # la somme
  • movq %mm0, %rax
  • movb $4, %cl # boucle de cl=4 jusqu'à 0 exclu
  • Somme: movq %rax, %rbx
  • andq $0xFFFF, %rbx # mot 16 bits de poids faible
  • addq %rbx, %rdx # ajoute à %rdx
  • shrq $16, %rax # décale %rax de 16 bits vers la droite
  • subb $1, %cl # compteur
  • jne Somme
  • popq %rcx
  • popq %rbx
  • popq %rax
  • ret
  • AfficheMatrice16:
  • movb $4, %cl # indice colonne
  • movq 8(%rsp), %rsi # pointeur vers la matrice
  • TraiteLigne16:
  • movb $4, %ch # indice ligne
  • TraiteElement16:
  • movq $FormatString16, %rdi # pointeur vers la chaîne de
  • # formatage
  • movq $0, %rax # stdout
  • pushq %rcx # sauve rcx car modifié par la fonction printf
  • pushq %rsi # sauve rsi car utilisé comme paramètre par la
  • # fonction printf
  • movq $0, %rbx# pour ne récuperer qu'un octet dans %rsi
  • movw (%rsi), %bx # récupère le mot 16 bits à afficher
  • movq %rbx, %rsi # %rsi est le paramètre de donnée
  • # pour printf
  • call printf
  • popq %rsi
  • popq %rcx
  • addq $2, %rsi # element suivant de la matrice
  • subb $1, %ch # indice suivant
  • jnz TraiteElement16 # traite l'élément suivant dans la ligne
  • movq $RetourChariot, %rdi # pointeur vers la chaîne saut
  • # à la ligne
  • movq $0, %rax # stdout
  • pushq %rcx # sauve rcx car modifié par la fonction printf
  • pushq %rsi # sauve rsi car utilisé comme paramètre par la
  • # fonction printf
  • call printf # affiche un saut à la ligne
  • popq %rsi
  • popq %rcx
  • subb $1, %cl # ligne suivante
  • jnz TraiteLigne16
  • movq $RetourChariot, %rdi # pointeur vers la chaîne
  • # saut à la ligne
  • movq $0, %rax # stdout
  • call printf # affiche un saut à la ligne
  • ret $8
  • AfficheMatrice32:
  • movb $4, %cl # indice colonne
  • movq 8(%rsp), %rsi # pointeur vers la matrice
  • TraiteLigne32:
  • movb $4, %ch # indice ligne
  • TraiteElement32:
  • movq $FormatString32, %rdi # pointeur vers la chaîne
  • # de formatage
  • movq $0, %rax # stdout
  • pushq %rcx # sauve rcx car modifié par la
  • # fonction printf
  • pushq %rsi # sauve rsi car utilisé comme
  • # paramètre par la fonction printf
  • movq $0, %rbx # pour ne récuperer qu'un octet dans %rsi
  • movl (%rsi), %ebx # récupère l'octet à afficher
  • movq %rbx, %rsi # %rsi est le paramètre de donnée pour
  • # printf
  • call printf
  • popq %rsi
  • popq %rcx
  • addq $4, %rsi # element suivant de la matrice
  • subb $1, %ch # indice suivant
  • jnz TraiteElement32 # traite l'élément suivant dans la ligne
  • movq $RetourChariot, %rdi # pointeur vers la chaîne saut à
  • # la ligne
  • movq $0, %rax # stdout
  • pushq %rcx # sauve rcx car modifié
  • # par la fonction printf
  • pushq %rsi # sauve rsi car utilisé comme
  • # paramètre par la fonction printf
  • call printf # affiche un saut à la ligne
  • popq %rsi
  • popq %rcx
  • subb $1, %cl # ligne suivante
  • jnz TraiteLigne32
  • movq $RetourChariot, %rdi # pointeur vers la chaîne saut
  • #à la ligne
  • movq $0, %rax # stdout
  • call printf # affiche un saut à la ligne
  • ret $8
  • AfficheChaineSimple:
  • movq 8(%rsp), %rdi
  • movq $0, %rax
  • call printf
  • ret $8
	.data		# directive de création d'une zone de donnée
	.align 8

m1:	.word	 0, 1, 2, 3 
	.word	 4, 5, 6, 7
	.word	 8, 9, 10, 11
	.word	12, 13, 14, 15

m2:	.word	 0, 4, 8, 12 
	.word	 1, 5, 9, 13
	.word	 2, 6, 10, 14
	.word	 3, 7, 11, 15

m3:	.long	 0, 0, 0, 0
	.long	 0, 0, 0, 0
	.long	 0, 0, 0, 0
	.long	 0, 0, 0, 0

FormatString16:			# pour les appels à printf
	.string	" %.3d"
FormatString32:			# pour les appels à printf
	.string	" %.6ld"
RetourChariot:
	.string "\n"
Annoncem1:
	.string "matrice m1:\n"
Annoncem2:
	.string "matrice m2:\n"
Annoncem22:
	.string "matrice m2 pivotée:\n"
Annoncem3:
	.string "m1 x m2 = \n"


	.text		# directive de création d'une zone d'instructions
	.globl main	# directive de création d'une étiquette 
main:			# main est l'adresse de début du programme 
	pushq	$Annoncem1
	call	AfficheChaineSimple	
	pushq	$m1
	call AfficheMatrice16	# Affiche la première matrice
	pushq	$Annoncem2
	call	AfficheChaineSimple	
	pushq	$m2				
	call AfficheMatrice16	# Affiche la deuxième matrice
	pushq	$m1
	pushq	$m2
	pushq	$m3
	call	ProduitScalaire
	pushq	$Annoncem22
	call	AfficheChaineSimple	
	pushq	$m2
	call AfficheMatrice16	# Affiche la deuxième matrice après
				# inversion ligne/colonnes
	pushq	$Annoncem3
	call	AfficheChaineSimple	
	pushq	$m3
	call AfficheMatrice32	# Affiche la matrice résultat

	movq    $1,%rax		# sélection de la fonction exit 
				# du système
        xorq    %rbx,%rbx	# mise à zéro du 1er paramètre en
				# utilisant xor, c'est à dire ou exclusif
	int     $0x80		# appel de l'interruption 
				# 128 -> GNU/Linux
fin:    ret	

ProduitScalaire:
	movq	16(%rsp), %rdi	# adresse de la deuxième matrice
	pushq	%rdi		# pivote la 2e matrice pour avoir les
				# vecteurs colonnes
	call	Pivote		# en lignes

	movq	 8(%rsp), %rcx	# adresse de la matrice produit
	movq	16(%rsp), %rdi	# adresse de la deuxième matrice
	movq	24(%rsp), %rsi	# adresse de la première matrice
	movq	$0, %rax	# indice de la ligne de la première
				# matrice
TraiteLigne:
	movq	$0, %rbx	# indice de la ligne de la transposée 
				# de la seconde matrice
TraiteColonne:
	movq	(%rsi, %rax, 8), %mm0	# charge la ligne de la 1ere
					# matrice dans mm0
	movq	(%rdi, %rbx, 8), %mm1	# charge la colonne de la 2e
					# matrice (ou ligne de sa
					# transposée) dans mm1
	pmullw	%mm1, %mm0	# %mm0 : partie basse du produit
				# composante par composante
	call	SommeDesComposantes	# rdx contient la somme des
					# composantes 8 bits de %mm0		
	movw	%dx, (%rcx)		# copie du résultat dans la
					# matrice produit
	movq	(%rsi, %rax, 8), %mm0	# charge la ligne de la 1ere
					# matrice dans mm0
	pmulhw	%mm1, %mm0		# %mm0 : partie haute du produit
					# composante par composante
	call	SommeDesComposantes	# rdx contient la somme des
				# composantes 8 bits de %mm0
	shll	$16, %edx	# décale le résultat de 16 bits vers la
				# gauche pour le mettre en partie haute		
	addl	%edx, (%rcx)	# ajoute la partie haute du résultat dans
				# la matrice produit
	addq	$4, %rcx	# pointe sur l'élément suivant à calculer
	addq	$1, %rbx	# indice de colonne suivant
	cmpq	$4, %rbx	# fin de colonne ?
	jne	TraiteColonne
	movq	$0, %rbx	# on recommence à la colonne 0
	addq	$1, %rax	# ligne suivante
	cmpq	$4, %rax	# dernière ligne ?
	jne	TraiteLigne	
	ret $24

Pivote: movq	8(%rsp), %rsi	# adresse de la matrice à pivoter
	movq	$0,	%rax	# indice de ligne (l)
	movq	$0,	%rbx	# indice de colonne (c)
TraiteElement:
	cmpq	%rax,	%rbx			
	jbe	ColSuivante	# élément suivant si l<=c
	movq	%rsi, %rdi	# on va échanger l'élément (l,c) 
				# avec l'élément (c,l)
	addq	%rax, %rdi
	addq	%rax, %rdi	# rdi:base + l * 2
	pushw	(%rdi, %rbx, 8)	# élément (l,c) -> pile
	movq	%rsi, %rdx
	addq	%rbx, %rdx
	addq	%rbx, %rdx	# rdx:base + c*2
	pushw	(%rdx, %rax, 8)	# élément (c,l) -> pile
	popw	%cx
	movw	%cx, (%rdi, %rbx, 8)# pile -> élément (l, c)	
	popw	%cx
	movw	%cx, (%rdx, %rax, 8)# pile -> element (c ,l)
ColSuivante:
	addq	$1, %rbx
	cmpq	$4, %rbx
	jne	TraiteElement
	movq	$0, %rbx	# retour à la colonne 0
	addq	$1, %rax	# ligne suivante
	cmpq	$4, %rax		
	jne	TraiteElement
	ret $8

SommeDesComposantes:
	pushq	%rax		# sauvegarde
	pushq	%rbx		# sauvegarde
	pushq	%rcx		# sauvegarde
	movq	$0,	%rdx	# la somme	
	movq	%mm0, 	%rax	
	movb	$4,	%cl	# boucle de cl=4 jusqu'à 0 exclu		
Somme:	movq	%rax, 	%rbx
	andq	$0xFFFF, %rbx	# mot 16 bits de poids faible
	addq	%rbx,	%rdx	# ajoute à %rdx
	shrq	$16, 	%rax	# décale %rax de 16 bits vers la droite
	subb	$1,	%cl	# compteur
	jne	Somme
	popq	%rcx
	popq	%rbx
	popq	%rax
	ret

AfficheMatrice16:
	movb	$4, %cl		# indice colonne
	movq	8(%rsp), %rsi	# pointeur vers la matrice
TraiteLigne16:
	movb	$4, %ch		# indice ligne
TraiteElement16:
	movq	$FormatString16, %rdi	# pointeur vers la chaîne de
					# formatage
	movq	$0, %rax	# stdout
	pushq	%rcx	# sauve rcx car modifié par la fonction printf	
	pushq	%rsi	# sauve rsi car utilisé comme paramètre par la
			# fonction printf
	movq	$0, %rbx# pour ne récuperer qu'un octet dans %rsi
	movw	(%rsi), %bx	# récupère le mot 16 bits à afficher
	movq	%rbx,	%rsi	# %rsi est le paramètre de donnée 
				# pour printf
	call	printf
	popq	%rsi
	popq	%rcx
	addq	$2, %rsi	# element suivant de la matrice
	subb	$1, %ch		# indice suivant
	jnz	TraiteElement16	# traite l'élément suivant dans la ligne
	movq	$RetourChariot, %rdi	# pointeur vers la chaîne saut
					# à la ligne
	movq	$0, %rax		# stdout
	pushq	%rcx	# sauve rcx car modifié par la fonction printf	
	pushq	%rsi	# sauve rsi car utilisé comme paramètre par la
			# fonction printf
	call	printf	# affiche un saut à la ligne
	popq	%rsi
	popq	%rcx
	subb	$1, %cl	# ligne suivante
	jnz	TraiteLigne16
	movq	$RetourChariot, %rdi	# pointeur vers la chaîne 
					# saut à la ligne
	movq	$0, %rax		# stdout
	call	printf			# affiche un saut à la ligne
	ret $8

AfficheMatrice32:
	movb	$4, %cl		# indice colonne
	movq	8(%rsp), %rsi	# pointeur vers la matrice
TraiteLigne32:
	movb	$4, %ch		# indice ligne
TraiteElement32:
	movq	$FormatString32, %rdi	# pointeur vers la chaîne 
					# de formatage
	movq	$0, %rax		# stdout
	pushq	%rcx			# sauve rcx car modifié par la
					# fonction printf	
	pushq	%rsi		# sauve rsi car utilisé comme
				# paramètre par la fonction printf
	movq	$0, %rbx	# pour ne récuperer qu'un octet dans %rsi
	movl	(%rsi), %ebx	# récupère l'octet à afficher
	movq	%rbx,	%rsi	# %rsi est le paramètre de donnée pour
				#  printf
	call	printf
	popq	%rsi
	popq	%rcx
	addq	$4, %rsi	# element suivant de la matrice
	subb	$1, %ch		# indice suivant
	jnz	TraiteElement32	# traite l'élément suivant dans la ligne
	movq	$RetourChariot, %rdi	# pointeur vers la chaîne saut à
				# la ligne
	movq	$0, %rax	# stdout
	pushq	%rcx		# sauve rcx car modifié 
				# par la fonction printf	
	pushq	%rsi		# sauve rsi car utilisé comme
				# paramètre par la fonction printf
	call	printf		# affiche un saut à la ligne
	popq	%rsi
	popq	%rcx
	subb	$1, %cl		# ligne suivante
	jnz	TraiteLigne32
	movq	$RetourChariot, %rdi	# pointeur vers la chaîne saut 
					#à la ligne
	movq	$0, %rax		# stdout
	call	printf			# affiche un saut à la ligne
	ret $8

AfficheChaineSimple:
	movq	8(%rsp), %rdi
	movq	$0, %rax
	call 	printf
	ret	$8

 Conclusion

jourlin@pc-jourlin:~/Test/asm$ gcc produit.s
jourlin@pc-jourlin:~/Test/asm$ ./a.out
matrice m1:
000 001 002 003
004 005 006 007
008 009 010 011
012 013 014 015

matrice m2:
000 004 008 012
001 005 009 013
002 006 010 014
003 007 011 015

matrice m2 pivotée:
000 001 002 003
004 005 006 007
008 009 010 011
012 013 014 015

m1 x m2 =
000014 000038 000062 000086
000038 000126 000214 000302
000062 000214 000366 000518
000086 000302 000518 000734

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  • produit.sTélécharger ce fichier [Réservé aux membres club]7 226 octets

Télécharger le zip


 Sources de la même categorie

Source avec Zip Source avec une capture LISTING DES PÉRIPHÉRIQUES PCI par _dune2_
Source avec Zip [LINUX] LIRE CLAVIER ET ECRIRE CONSOLE par sheorogath
UN "HELLO WORLD" SOUS LINUX (UTILISE L'ASSEMBLEUR AS ET LE L... par bouba
HELLO WORLD NUNUX G++! MOUARF.. par Lion7

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture LE SYSTÈME D'EXPLOITATION LOGRAM par steckdenis

Commentaires et avis

Aucun commentaire pour le moment.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Routine asm dans gcc [ par Juke ] quelqu'un connait t'il un txt en francais qui explik comment incorporer de l'asm dans du c++ avec gcc ou dev-c++ ? faire du C en mode reel avec gcc [ par ninis ] Je n'arrive pas a generer du code en mode protege sur une archi i386 avec gcc ... kelk1 saurait comment generer des fichiers .o dans ce mode ?? Utilisation de printf avec compilo GCC [ par MattXSFR ] J'ai un petit problème assez étrange, et j'arrive pas à le résoudre.J'ai fait un programme en ASM syntaxe GNU qui utilise la fonction printf pour affi CONVERSION SYNTAXE GCC VERS INTEL [ par BruNews ] CONVERSION SYNTAXE GCC VERS INTELSalut,j'ai un fichier asm (*.s) dans un projet en C qui compile sur GCC. Faut que je traduise depuis cette syntaxe bi assembleur en ligne avec gcc [ par nalk_deen_mook ] Bonjour quelqu'un pourrait il mexpliquer pourquoi ce bout de code ne&nbsp; fonctionne pas#include&lt;stdio.h&gt; int main(){&nbsp; int a=10,b;&nbsp;_a Debutant en SSE / SIMD [ par epineurien ] Bonsoir à tous !Je débute en SSE et je suis confronté à un léger problême : mon compilateur refuse tout ce que je lui demande.Bon , pour être exact j' GNU Assembleur et manipulation de structure. [ par 000000 ] Bonjour, J'ai un petit soucis en ce qui concerne la manipulation de structure. Je possède un pointeur vers une structure x dont je souhaite recupurer


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,328 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales