Μια προηγούμενη ενότητα παρουσίασε τις συσκευασμένες τιμές κινητής υποδιαστολής: πολλούς αριθμούς σε έναν καταχωρητή xmm, πάνω στους οποίους γίνονται πράξεις ανά λωρίδα και παράλληλα.
Οι ίδιοι καταχωρητές xmm μπορούν επίσης να κρατούν συσκευασμένους ακεραίους.
Το μεγαλύτερο μέρος του μοντέλου SIMD κινητής υποδιαστολής μεταφέρεται αναλλοίωτο στους συσκευασμένους ακεραίους:
Ωστόσο, η σύνταξη είναι ελαφρώς διαφορετική:
p που δηλώνει ότι η εντολή εκτελεί πράξεις σε συσκευασμένα δεδομένα.add, mul κ.λπ.).Οι συσκευασμένοι ακέραιοι έχουν τέσσερα μεγέθη λωρίδας, και καθένα έχει το δικό του επίθημα:
| πλάτος λωρίδας | byte | λωρίδες σε 128 bit | επίθημα |
|---|---|---|---|
| byte | 1 | 16 | b |
| λέξη | 2 | 8 | w |
| διπλή λέξη | 4 | 4 | d |
| τετραπλή λέξη | 8 | 2 | q |
Για παράδειγμα:
| εντολή | σημασία |
|---|---|
paddb |
συσκευασμένο add, λωρίδες 8 bit (16 λωρίδες) |
paddw |
συσκευασμένο add, λωρίδες 16 bit (8 λωρίδες) |
paddd |
συσκευασμένο add, λωρίδες 32 bit (4 λωρίδες) |
paddq |
συσκευασμένο add, λωρίδες 64 bit (2 λωρίδες) |
Ορισμένες εντολές δέχονται λωρίδες ενός μεγέθους ως είσοδο, αλλά άλλου μεγέθους ως έξοδο. Ακολουθούν την ίδια γενική σύμβαση, αλλά με δύο επιθήματα μεγέθους. Το πρώτο δηλώνει το μέγεθος της λωρίδας εισόδου, το δεύτερο το μέγεθος της λωρίδας εξόδου:
| εντολή | σημασία |
|---|---|
pmovsxwd |
συσκευασμένο movsx, από λωρίδες 16 bit σε λωρίδες 32 bit |
pmuldq |
συσκευασμένο mul, από λωρίδες 32 bit σε λωρίδες 64 bit |
Δύο εντολές με όνομα ακεραίων αντιγράφουν 128 bit μεταξύ ενός καταχωρητή xmm και της μνήμης:
| εντολή | περιγραφή |
|---|---|
movdqa |
αντιγράφει συσκευασμένους ακεραίους από ή προς ευθυγραμμισμένη θέση |
movdqu |
αντιγράφει συσκευασμένους ακεραίους από ή προς μη ευθυγραμμισμένη θέση |
Συμπεριφέρονται όπως οι movaps και movups: η movdqa προκαλεί σφάλμα σε μη ευθυγραμμισμένη διεύθυνση, ενώ η movdqu δέχεται οποιαδήποτε.
Και οι τέσσερις αντιγράφουν 128 bit χωρίς να τα ερμηνεύουν.
Το ζεύγος με όνομα ακεραίων χρησιμοποιείται με ακέραια δεδομένα από σύμβαση, όχι από υποχρέωση.
Το dq εδώ σημαίνει double-qword, δηλαδή 128 bit (16 byte).
Η πρόσθεση και η αφαίρεση ακολουθούν τον κανόνα ονομασίας:
paddb xmm0, xmm1 ; 16 lanes: each 8-bit, xmm0 += xmm1
paddw xmm2, xmm3 ; 8 lanes: each 16-bit, xmm2 += xmm3
psubd xmm4, xmm5 ; 4 lanes: each 32-bit, xmm4 -= xmm5
psubq xmm6, xmm7 ; 2 lanes: each 64-bit, xmm6 -= xmm7
Δεν υπάρχει ξεχωριστή μορφή για προσημασμένα και μη προσημασμένα.
Στο συμπλήρωμα ως προς δύο, η πρόσθεση και η αφαίρεση παράγουν τα ίδια bit είτε οι λωρίδες διαβάζονται ως προσημασμένες είτε ως μη προσημασμένες, οπότε μία εντολή εξυπηρετεί και τις δύο.
Η ερμηνεία είναι δική σου, ακριβώς όπως με τα βαθμωτά add και sub.
Αυτές οι εντολές αναδιπλώνονται σε περίπτωση υπερχείλισης, όπως τα βαθμωτά αντίστοιχά τους.
Μια λωρίδα 8 bit κρατά τιμές modulo 256, οπότε ένα paddb του 200 + 100 παράγει 300 - 256 = 44, απορρίπτοντας τα bit που δεν χωρούν.
Σημείωσε ότι αυτά τα επιπλέον bit δεν μεταφέρονται στην επόμενη λωρίδα. Κάθε λωρίδα υφίσταται πράξεις ξεχωριστά από τις άλλες, παρόλο που μοιράζονται τον ίδιο καταχωρητή.
Το SIMD ακεραίων προσθέτει μια πράξη που το SIMD κινητής υποδιαστολής δεν έχει: πρόσθεση και αφαίρεση με κορεσμό, που περιορίζουν αντί να αναδιπλώνουν. Ένα αποτέλεσμα πάνω από το εύρος της λωρίδας γίνεται η μεγαλύτερη τιμή που χωρά η λωρίδα; ένα αποτέλεσμα κάτω από το εύρος γίνεται η μικρότερη.
Οι μορφές με κορεσμό εισάγουν s (προσημασμένα) ή us (μη προσημασμένα) πριν από το επίθημα μεγέθους:
| εντολή | σημασία |
|---|---|
paddsb |
add, με κορεσμό, προσημασμένες λωρίδες 8 bit |
paddusb |
add, με κορεσμό, μη προσημασμένες λωρίδες 8 bit |
psubsw |
sub, με κορεσμό, προσημασμένες λωρίδες 16 bit |
psubusw |
sub, με κορεσμό, μη προσημασμένες λωρίδες 16 bit |
Το εύρος περιορισμού είναι το πλήρες παριστάμενο εύρος για έναν ακέραιο του αντίστοιχου μεγέθους και προσήμου. Για ένα byte:
[0, 255]: ένα paddusb του 200 + 100 δίνει 255, και ένα psubusb του 5 - 10 δίνει 0.[-128, 127]: ένα paddsb του 100 + 50 δίνει 127.Ο κορεσμός έχει σημασία όταν μια λωρίδα κρατά μια φραγμένη ποσότητα, όπως ένα κανάλι εικονοστοιχείου ή ένα δείγμα ήχου. Η αναδίπλωση θα έκανε ένα πολύ φωτεινό εικονοστοιχείο σκοτεινό, ενώ ο περιορισμός το κρατά στη μέγιστη φωτεινότητα, που είναι το αποτέλεσμα που θέλεις.
Η πρόσθεση και η αφαίρεση με κορεσμό υπάρχουν μόνο για λωρίδες byte και λέξης, όχι για λωρίδες διπλής ή τετραπλής λέξης.
Ο πολλαπλασιασμός δύο τιμών N bit μπορεί να παράγει γινόμενο 2N bit, αλλά η λωρίδα προορισμού έχει πλάτος μόνο N bit. Οι πράξεις SIMD το λύνουν αυτό ορίζοντας ποιο μισό του γινομένου θα κρατηθεί, είτε τα χαμηλά N bit είτε τα υψηλά N bit.
Για λωρίδες 16 bit χρησιμοποιούνται τρεις εντολές:
| εντολή | σημασία |
|---|---|
pmullw |
mul, λωρίδες 16 bit, κρατά τα χαμηλά 16 bit κάθε γινομένου |
pmulhw |
mul, λωρίδες 16 bit, κρατά τα υψηλά 16 bit, προσημασμένοι τελεστέοι |
pmulhuw |
mul, λωρίδες 16 bit, κρατά τα υψηλά 16 bit, μη προσημασμένοι τελεστέοι |
Τα χαμηλά 16 bit ενός γινομένου είναι ίδια είτε οι τελεστέοι διαβάζονται ως προσημασμένοι είτε ως μη προσημασμένοι, γι' αυτό υπάρχει μόνο μία pmullw.
Τα υψηλά 16 bit, ωστόσο, διαφέρουν ανάλογα με το πρόσημο του αποτελέσματος. Γι' αυτό ο πολλαπλασιασμός του υψηλού μισού έχει ξεχωριστές μορφές για προσημασμένο και μη προσημασμένο πολλαπλασιασμό:
pmulhw, για προσημασμένο πολλαπλασιασμό.pmulhuw, με ένα επιπλέον u, για μη προσημασμένο πολλαπλασιασμό.Πρόσεξε τη σύνταξη:
p, για συσκευασμένο ακέραιο.mul.h, που δηλώνει ότι επιλέγονται τα πάνω ("υψηλά") bit του αποτελέσματος.u αν το αποτέλεσμα πρέπει να ερμηνευτεί ως μη προσημασμένο (δηλαδή δεν γίνεται επέκταση προσήμου).w, που δηλώνει ότι πρόκειται για πράξη σε λέξη (16 bit).Ο συσκευασμένος πολλαπλασιασμός για λέξεις ακολουθεί ακριβώς τον παραπάνω κανόνα.
Ο πολλαπλασιασμός διπλής λέξης (32 bit) ακολουθεί επίσης τον κανόνα, αλλά υπάρχει μόνο η παραλλαγή που επιλέγει το χαμηλό μισό: pmulld.
Δεν υπάρχει παραλλαγή για πολλαπλασιασμό διπλής λέξης που να επιλέγει τα υψηλά bit. Ωστόσο, υπάρχουν παραλλαγές που διευρύνουν τον πολλαπλασιασμό, αποθηκεύοντας το πλήρες γινόμενο 64 bit των λωρίδων στις άρτιες θέσεις (δηλαδή των λωρίδων στις θέσεις 0 και 2):
| εντολή | σημασία |
|---|---|
pmuludq |
πολλαπλασιάζει τα μη προσημασμένα στοιχεία 32 bit στις άρτιες θέσεις σε 2 πλήρη γινόμενα 64 bit |
pmuldq |
πολλαπλασιάζει τα προσημασμένα στοιχεία 32 bit στις άρτιες θέσεις σε 2 πλήρη γινόμενα 64 bit |
Πρόσεξε ότι η σύνταξη χρησιμοποιεί dq, πιθανώς με ένα u πριν από αυτό για μη προσημασμένο πολλαπλασιασμό.
Αυτό συμβαίνει επειδή οι εντολές δέχονται λωρίδες dword και βγάζουν λωρίδες qword.
Δεν υπάρχει συσκευασμένη διαίρεση ακεραίων. Ο κώδικας που τη χρειάζεται μετατρέπει τις τιμές σε αριθμούς κινητής υποδιαστολής, διαιρεί και μετατρέπει πάλι πίσω.
Υπάρχουν συσκευασμένα αντίστοιχα των movsx και movzx.
Ακολουθούν την ίδια σύνταξη που αναφέραμε για εντολές που δέχονται εισόδους με διαφορετικό μέγεθος λωρίδας από την έξοδό τους:
pmovsxwd xmm0, xmm1 ; 4 words -> 4 dwords, sign-extended
pmovzxbw xmm0, xmm1 ; 8 bytes -> 8 words, zero-extended
Σημείωσε ότι ο αριθμός των λωρίδων καθορίζεται από το μεγαλύτερο πλάτος (της εξόδου).
Η εντολή διαβάζει τόσες λωρίδες από το χαμηλό μέρος της πηγής.
Αυτή είναι η ίδια σημασιολογία που έχουμε ήδη δει για τις συσκευασμένες εντολές cvt μεταξύ αριθμών κινητής υποδιαστολής απλής και διπλής ακρίβειας.
Υπάρχουν εντολές για μετατροπή μεταξύ προσημασμένων ακεραίων 32 bit και λωρίδων κινητής υποδιαστολής.
Ακολουθούν τη συνήθη σύνταξη των εντολών cvt και cvtt, αλλά αντί για si ένας συσκευασμένος ακέραιος αντιπροσωπεύεται από dq:
cvtdq2ps xmm0, xmm1 ; convert 32-bit signed integers in xmm1 to 32-bit floats in xmm0
cvtdq2pd xmm2, xmm3 ; convert 32-bit signed integers in xmm3 to 64-bit floats in xmm2
cvtps2dq xmm4, xmm5 ; convert 32-bit floats in xmm5 to 32-bit signed integers in xmm4
Οι εντολές που χρησιμοποιούν pi για να αντιπροσωπεύσουν συσκευασμένους ακεραίους γράφουν σε παλαιούς καταχωρητές mmx και είναι στην πράξη παρωχημένες στο x86-64.
Προτίμησε τις μορφές dq, που χρησιμοποιούν καταχωρητές xmm.
Τα ίδια σχόλια που έγιναν για τη βαθμωτή μετατροπή μεταξύ αριθμών κινητής υποδιαστολής και ακεραίων ισχύουν και εδώ.
Οι αριθμοί κινητής υποδιαστολής στρογγυλοποιούνται σύμφωνα με έναν ειδικό καταχωρητή που λέγεται MXCSR, τη λειτουργία του οποίου δεν μπορείς να υποθέσεις κατά την είσοδο σε μια συνάρτηση.
Υπάρχει μια παραλλαγή cvtt (με ένα επιπλέον t) που αποκόπτει πάντα το αποτέλεσμα.
Είναι επίσης δυνατό να χρησιμοποιήσεις το round για να φέρεις τις συσκευασμένες τιμές κινητής υποδιαστολής σε γνωστή κατάσταση πριν τη μετατροπή.
Η τιμή ελέγχου στρογγυλοποίησης είναι ίδια με του βαθμωτού round και η σύνταξη είναι επίσης ίδια για συσκευασμένες τιμές κινητής υποδιαστολής:
roundps xmm0, xmm1, 1 ; xmm0 = floor(xmm1), packed 32-bit floats
roundpd xmm2, xmm3, 2 ; xmm2 = ceil(xmm3), packed 64-bit floats
Γράφεις τον ψηφιακό πυρήνα μιας μικρής κονσόλας μίξης σε ένα στούντιο ηχογράφησης.
Ο ήχος φτάνει ως ροή δειγμάτων. Κάθε δείγμα είναι ένας αριθμός που περιγράφει τη θέση του κώνου ενός μεγαφώνου τη δεδομένη στιγμή. Η κονσόλα επεξεργάζεται ένα ολόκληρο μπλοκ δειγμάτων ταυτόχρονα, εφαρμόζοντας την ίδια πράξη σε κάθε ένα.
Έχεις πέντε εργασίες, καθεμία από τις οποίες επεξεργάζεται ένα μπλοκ δειγμάτων που βρίσκεται στη μνήμη. Λαμβάνεις τους τελεστέους μέσω διευθύνσεων μνήμης και γράφεις την απάντησή σου μέσω μιας διεύθυνσης αποτελέσματος.
Οι υπολογισμοί σε αυτή την άσκηση πρέπει να γίνονται με εντολές SIMD, όχι με βαθμωτές πράξεις.
Το στούντιο μερικές φορές ηχογραφεί όργανα σε διαφορετικά κομμάτια. Για να τα ακούσεις από τα ίδια ηχεία, αθροίζεις τα δύο κομμάτια σε ένα.
Υλοποίησε τη συνάρτηση mix_tracks, η οποία προσθέτει δύο κομμάτια μεταξύ τους, δείγμα προς δείγμα.
Κάθε κομμάτι είναι ένα μπλοκ από 8 προσημασμένα δείγματα 16 bit.
Ένα άθροισμα που υπερχειλίζει το εύρος των προσημασμένων 16 bit πρέπει να περιορίζεται αντί να αναδιπλώνεται.
Αυτή η συνάρτηση παίρνει ως ορίσματα, με αυτή τη σειρά:
result: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte για ένα buffer όπου γράφονται τα 8 αναμεμειγμένα δείγματα.track_a: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte του πρώτου κομματιού, με 8 προσημασμένα δείγματα 16 bit.track_b: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte του δεύτερου κομματιού, με 8 προσημασμένα δείγματα 16 bit.track_a = {10000, 30000, 20000, -30000, -20000, -100, 100, 0}
track_b = { 5000, 5000, 20000, -5000, -20000, 100, -100, 0}
result = {15000, 32767, 32767, -32768, -32768, 0, 0, 0}
Αυτή η συνάρτηση δεν έχει τιμή επιστροφής.
Όταν δύο μικρόφωνα ηχογραφούν ταυτόχρονα, το καθένα πιάνει ένα αμυδρό αντίγραφο της πηγής του άλλου. Αυτό το ανεπιθύμητο αντίγραφο ονομάζεται διαρροή. Μόλις μετρηθεί αυτή η διαρροή, πρέπει να αφαιρεθεί και πάλι για να καθαρίσει το κομμάτι.
Υλοποίησε τη συνάρτηση remove_bleed, η οποία αφαιρεί το μπλοκ της διαρροής από το μπλοκ του κομματιού, δείγμα προς δείγμα.
Κάθε μπλοκ είναι 8 προσημασμένα δείγματα 16 bit και η αφαίρεση πρέπει να γίνεται με κορεσμό.
Αυτή η συνάρτηση παίρνει ως ορίσματα, με αυτή τη σειρά:
result: διεύθυνση μνήμης όπου γράφονται τα 8 καθαρισμένα δείγματα (η ευθυγράμμιση δεν είναι εγγυημένη).track: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte του ηχογραφημένου κομματιού, 8 προσημασμένα δείγματα 16 bit.bleed: διεύθυνση μνήμης της διαρροής προς αφαίρεση, 8 προσημασμένα δείγματα 16 bit (η ευθυγράμμιση δεν είναι εγγυημένη).track = {10000, -30000, 5000, 32767, 0, 200, -200, 15000}
bleed = { 2000, 5000, 5000, -5, 0, 300, 300, 5000}
result = { 8000, -32768, 0, 32767, 0, -100, -500, 10000}
Αυτή η συνάρτηση δεν έχει τιμή επιστροφής.
Πάνω από κάθε κανάλι βρίσκεται ένας μετρητής στάθμης, μια μικρή ράβδος της οποίας η φωτεινότητα δείχνει πόσο δυνατό είναι αυτό το κανάλι. Το μπροστινό πάνελ έχει έναν κεντρικό μετρητή που πρέπει να λάμπει τόσο φωτεινά όσο τα δύο κανάλια μαζί. Αθροίζεις τα δύο μπλοκ του μετρητή για να τον οδηγήσεις.
Σημείωσε ότι ένας φωτεινός μετρητής μένει στη μέγιστη φωτεινότητα αντί να γυρίζει πίσω στο σκοτάδι, οπότε το άθροισμα γίνεται με κορεσμό.
Υλοποίησε τη συνάρτηση combine_meters, η οποία προσθέτει δύο μπλοκ του μετρητή δείγμα προς δείγμα.
Αυτή η συνάρτηση παίρνει ως ορίσματα, με αυτή τη σειρά:
result: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte όπου γράφονται οι 16 συνδυασμένες τιμές.meter_a: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte του μπλοκ του μετρητή του πρώτου καναλιού, με 16 συσκευασμένες ανυπόγραφες τιμές 8 bit.meter_b: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte του μπλοκ του μετρητή του δεύτερου καναλιού, με 16 συσκευασμένες ανυπόγραφες τιμές 8 bit.Κάθε μπλοκ είναι 16 ανυπόγραφες τιμές 8 bit. Πρέπει να προστεθούν μεταξύ τους, με κορεσμό στο ανυπόγραφο εύρος.
meter_a = {200, 100, 50, 255, 0, 128, 10, 240, 1, 2, 3, 4, 5, 6, 7, 8}
meter_b = {100, 100, 200, 1, 0, 128, 10, 20, 1, 2, 3, 4, 5, 6, 7, 8}
result = {255, 200, 250, 255, 0, 255, 20, 255, 2, 4, 6, 8, 10, 12, 14, 16}
Αυτή η συνάρτηση δεν έχει τιμή επιστροφής.
Το τραγούδι δεν πρέπει να σταματά απότομα, αλλά να σβήνει σταδιακά στο τέλος. Έχεις ένα μπλοκ από συντελεστές ενίσχυσης, έναν για κάθε δείγμα, που μειώνουν σταδιακά την ένταση, από πιο σιγά σε ακόμη πιο σιγά.
Κάθε συντελεστής είναι ένα κλάσμα εκφρασμένο πάνω στο 65536.
Για παράδειγμα, αν ένα δείγμα έχει τιμή 16384, στην πραγματικότητα εκφράζει το 16384 / 65536, που είναι 1 / 4.
Η μεγαλύτερη χρησιμοποιήσιμη τιμή, το 32767, είναι λίγο κάτω από το ένα δεύτερο.
Εφόσον το 65536 είναι 2^16, πολλαπλασιάζοντας ένα δείγμα με τον συντελεστή του και κρατώντας το υψηλό μισό του γινομένου προκύπτει sample * gain / 65536.
Υλοποίησε τη συνάρτηση apply_fade, η οποία κλιμακώνει κάθε δείγμα με τον συντελεστή του.
Αυτή η συνάρτηση παίρνει ως ορίσματα, με αυτή τη σειρά:
result: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte όπου γράφονται όλα τα κλιμακωμένα δείγματα.track: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte του κομματιού, με n προσημασμένα δείγματα 16 bit.gains: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte των συντελεστών ενίσχυσης, με n προσημασμένες τιμές 16 bit, καθεμία στο εύρος 0 έως 32767.n: ο αριθμός των δειγμάτων, που δεν είναι ποτέ μηδέν και είναι πάντα πολλαπλάσιο του 8, ως ανυπόγραφος ακέραιος 64 bit.Σημείωσε ότι το κομμάτι είναι ένας πίνακας που περιέχει n προσημασμένα δείγματα 16 bit, όπου το n δεν είναι ποτέ μηδέν και είναι πάντα πολλαπλάσιο του 8.
Για κάθε δείγμα, το κλιμακωμένο αποτέλεσμα είναι τα υψηλά 16 bit του προσημασμένου γινομένου: sample * gain.
track = {20000, 20000, 20000, 20000, -20000, -20000, -20000, -20000}
gains = {32767, 24576, 16384, 8192, 32767, 24576, 16384, 8192}
result = { 9999, 7500, 5000, 2500, -10000, -7500, -5000, -2500}
Το να κρατάς το υψηλό μισό στρογγυλοποιεί προς το αρνητικό άπειρο.
Γι' αυτό το 20000 * 32767 κλιμακώνεται σε 9999, ενώ το -20000 * 32767 κλιμακώνεται σε -10000 αντί για -9999.
Αυτή η συνάρτηση δεν έχει τιμή επιστροφής.
Ο ντράμερ ηχογραφήθηκε πολύ πιο δυνατά απ' ό,τι έπρεπε. Για να χαμηλώσεις όλο το κομμάτι, διαιρείς κάθε δείγμα με μια σταθερά.
Υλοποίησε τη συνάρτηση attenuate_track.
Αυτή η συνάρτηση παίρνει ως ορίσματα, με αυτή τη σειρά:
result: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte όπου γράφονται τα αποτελέσματα, ως προσημασμένοι ακέραιοι 32 bit.samples: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte των δειγμάτων, n προσημασμένες τιμές 16 bit.divisor: διεύθυνση μνήμης ευθυγραμμισμένη στα 16 byte με 4 πανομοιότυπα αντίγραφα του διαιρέτη, ως ακέραιοι 32 bit.n είναι ο αριθμός των δειγμάτων, που δεν είναι ποτέ μηδέν και είναι πάντα πολλαπλάσιο του 4, ως ανυπόγραφος ακέραιος 64 bit.Σημείωσε ότι το samples είναι ένας πίνακας που περιέχει n προσημασμένα δείγματα 16 bit, όπου το n δεν είναι ποτέ μηδέν και είναι πάντα πολλαπλάσιο του 4.
Ο διαιρέτης παρέχεται ως 4 αντίγραφα του ίδιου ακέραιου 32 bit, ήδη αντιγραμμένα ώστε να γεμίζουν και τις τέσσερις λωρίδες ταυτόχρονα.
Το ακέραιο SIMD δεν έχει συσκευασμένη διαίρεση, οπότε η δουλειά γίνεται σε συσκευασμένη κινητή υποδιαστολή και μετά μετατρέπεται πίσω σε συσκευασμένους ακέραιους 32 bit για να αποθηκευτεί στο result.
Μετέτρεψε πίσω με αποκοπή προς το μηδέν, ώστε ένα πηλίκο 2.3 να γίνει 2 και το -2.3 να γίνει -2.
samples = {300, 150, 90, -120, 100, 50, -50, 7}
divisor = {3, 3, 3, 3}
result = {100, 50, 30, -40, 33, 16, -16, 2}
Αυτή η συνάρτηση δεν έχει τιμή επιστροφής.
Γράψου στο Exercism για να μάθεις και να κατακτήσεις x86-64 Assembly με 22 έννοιες130 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.