x86 মেশিন কোড (এমএমএক্স / এসএসই 1), 26 বাইট (4x ইনট 16_t)
x86 মেশিন কোড (এসএসই 4.1), 28 বাইট (4x ইনট 32_ টি বা ইউএনটি 32_t)
x86 মেশিন কোড (এসএসই 2), 24 বাইট (4x ফ্লোট 32) বা 27 বি সিটি ভি 32 থেকে
(সর্বশেষ সংস্করণ যা ইন্টি 32-কে ফ্লোটে রূপান্তরিত করে একই বৃহত পূর্ণসংখ্যার জন্য একই ধাপে পুরোপুরি সঠিক নয় flo ফ্লোট ইনপুট সহ, গোল করা কলারের সমস্যা এবং কোনও এনএএন না থাকলে এই ফাংশনটি সঠিকভাবে কাজ করে যা তুলনামূলকভাবে ফ্লোটগুলি সনাক্ত করে == সর্বোচ্চটিতে। পূর্ণসংখ্যা সংস্করণগুলি সমস্ত ইনপুটগুলির জন্য কাজ করে, তাদেরকে স্বাক্ষরযুক্ত 2 এর পরিপূরক হিসাবে গণ্য করে))
এই সমস্তগুলি একই মেশিন কোড সহ 16/32/64-বিট মোডে কাজ করে।
একটি স্ট্যাক-আরগস কলিং কনভেনশনটি দু'বার আর্গুমেন্টগুলি লুপ করা সম্ভব করে তোলে (সর্বাধিক সন্ধান এবং তারপরে তুলনা করা), সম্ভবত আমাদের আরও একটি ছোট বাস্তবায়ন দেয়, তবে আমি সেই পদ্ধতির চেষ্টা করি নি।
x86 সিমডে ভেক্টর-> একটি একক নির্দেশ ( pmovmskb
বা movmskps
বা পিডি) হিসাবে পূর্ণসংখ্যার বিটম্যাপ রয়েছে , সুতরাং এমএমএক্স / এসএসই নির্দেশনা কমপক্ষে 3 বাইট দীর্ঘ হলেও এটির জন্য এটি স্বাভাবিক ছিল। এসএসইএস 3 এবং পরবর্তী নির্দেশাবলী এসএসই 2 এর চেয়ে দীর্ঘ এবং এমএমএক্স / এসএসই 1 নির্দেশাবলী সবচেয়ে কম। pmax*
এসএসই 1 (এমএমএক্স রেগের জন্য) এবং এসএসই 2 (এক্সএমএম রেগের জন্য) কেবল স্বাক্ষরযুক্ত শব্দ (16-বিট) এবং স্বাক্ষরবিহীন বাইট সহ বিভিন্ন সময়ে (প্যাকড-ইন্টিজার ভার্টিকাল ম্যাক্স) বিভিন্ন সংস্করণ প্রবর্তিত হয়েছিল।
( pshufw
এবং pmaxsw
এমএমএক্স-এ রেজিস্টারগুলি কাটমাই পেন্টিয়াম III এর সাথে নতুন, তাই তাদের কেবল এসএমই 1 প্রয়োজন, কেবলমাত্র এমএমএক্স সিপিইউ বৈশিষ্ট্য নয়))
এটি আই unsigned max4_mmx(__m64)
386 সিস্টেম ভি এবিআইয়ের মতো সি থেকে কলযোগ্য , যা একটি __m64
আর্গ পাস করে mm0
। (না x86-64 সিস্টেম ভী, যা পাসের __m64
মধ্যে xmm0
!)
line code bytes
num addr
1 global max4_mmx
2 ;; Input 4x int16_t in mm0
3 ;; output: bitmap in EAX
4 ;; clobbers: mm1, mm2
5 max4_mmx:
6 00000000 0F70C8B1 pshufw mm1, mm0, 0b10110001 ; swap adjacent pairs
7 00000004 0FEEC8 pmaxsw mm1, mm0
8
9 00000007 0F70D14E pshufw mm2, mm1, 0b01001110 ; swap high/low halves
10 0000000B 0FEECA pmaxsw mm1, mm2
11
12 0000000E 0F75C8 pcmpeqw mm1, mm0 ; 0 / -1
13 00000011 0F63C9 packsswb mm1, mm1 ; squish word elements to bytes, preserving sign bit
14
15 00000014 0FD7C1 pmovmskb eax, mm1 ; extract the high bit of each byte
16 00000017 240F and al, 0x0F ; zero out the 2nd copy of the bitmap in the high nibble
17 00000019 C3 ret
size = 0x1A = 26 bytes
যদি একটি pmovmskw
থাকত তবে কীটি packsswb
এবং and
(3 + 2 বাইট) সংরক্ষণ করতে পারত । আমাদের দরকার নেই and eax, 0x0f
কারণ pmovmskb
এমএমএক্স নিবন্ধে ইতিমধ্যে উপরের বাইটগুলি শূন্য করে। এমএমএক্স রেজিস্টারগুলি কেবল 8 বাইট প্রশস্ত, সুতরাং 8-বিট AL সমস্ত সম্ভাব্য নন-শূন্য বিটগুলি কভার করে।
যদি আমরা জানতাম যে আমাদের ইনপুটগুলি অ-নেতিবাচক ছিল, তবে আমরা পরবর্তীpacksswb mm1, mm0
4 টি বাইটে অ-নেতিবাচক স্বাক্ষরিত বাইটগুলি উত্পাদন করতে পারতামmm1
, and
পরে প্রয়োজনীয়তা এড়িয়ে pmovmskb
। এইভাবে 24 বাইট।
স্বাক্ষরিত স্যাচুরেশন সহ x86 প্যাকটি ইনপুট এবং আউটপুটটিকে স্বাক্ষরিত হিসাবে বিবেচনা করে, তাই এটি সর্বদা সাইন বিট সংরক্ষণ করে। ( https://www.felixcloutier.com/x86/packsswb:packssdw )। মজার বিষয়: স্বাক্ষরবিহীন সম্পৃক্তি সঙ্গে এক্স 86 প্যাক এখনও একইরূপে ইনপুট হিসাবে স্বাক্ষর করেন। এটি হতে পারে কেন PACKUSDW
এসএসই 4.1 অবধি প্রবর্তন করা হয়নি, অন্যদিকে 3 টি আকার এবং স্বাক্ষরের সংমিশ্রণ এমএমএক্স / এসএসই 2-এর পরে থেকেই ছিল।
অথবা একটি এক্সএমএম রেজিস্টারে 32-বিট ইন্টিজার সহ (এবং pshufd
পরিবর্তে pshufw
), প্রতিটি নির্দেশের জন্য movmskps
প্যাকটি প্রতিস্থাপন এবং / এবং বাদ দিয়ে আরও একটি উপসর্গ বাইট প্রয়োজন । তবে pmaxsd
/ pmaxud
অতিরিক্ত অতিরিক্ত বাইটের প্রয়োজন ...
unsigned max4_sse4(__m128i);
x86-64 সিস্টেম ভি, বা এমএসভিসি ভেক্টরক্যাল ( -Gv
) এর সাথে সি থেকে কলযোগ্য , উভয়ই এক্সএমএম রেগগুলিতে পাস __m128i
/ __m128d
/ __m128
আরগস দিয়ে শুরু হয় xmm0
।
20 global max4_sse4
21 ;; Input 4x int32_t in xmm0
22 ;; output: bitmap in EAX
23 ;; clobbers: xmm1, xmm2
24 max4_sse4:
25 00000020 660F70C8B1 pshufd xmm1, xmm0, 0b10110001 ; swap adjacent pairs
26 00000025 660F383DC8 pmaxsd xmm1, xmm0
27
28 0000002A 660F70D14E pshufd xmm2, xmm1, 0b01001110 ; swap high/low halves
29 0000002F 660F383DCA pmaxsd xmm1, xmm2
30
31 00000034 660F76C8 pcmpeqd xmm1, xmm0 ; 0 / -1
32
33 00000038 0F50C1 movmskps eax, xmm1 ; extract the high bit of each dword
34 0000003B C3 ret
size = 0x3C - 0x20 = 28 bytes
অথবা যদি আমরা ইনপুট হিসাবে গ্রহণ করি তবে আমরা float
এসএসই 1 নির্দেশাবলী ব্যবহার করতে পারি। float
বিন্যাস পূর্ণসংখ্যা মান বিস্তৃত উপস্থাপন করতে পারেন ...
বা যদি আপনি মনে করেন যে নিয়মগুলি খুব দূরে বাঁকানো 0F 5B C0 cvtdq2ps xmm0, xmm0
হয়েছে, রূপান্তর করতে 3 বাইট দিয়ে শুরু করুন , 27-বাইট ফাংশন তৈরি করুন যা সমস্ত পূর্ণসংখ্যার জন্য কাজ করে যা আইইইই বাইনারি 32 হিসাবে হুবহু উপস্থাপনযোগ্যfloat
এবং ইনপুটগুলির বেশ কয়েকটি সংমিশ্রণ যেখানে কিছু ইনপুট পায় রূপান্তরকালে 2, 4, 8, বা যাই হোক না কেন একাধিকতে গোল হয়। (সুতরাং এটি এসএসই 4.1 সংস্করণের চেয়ে 1 বাইট ছোট এবং কেবল এসএসই 2 দিয়ে কোনও x86-64 এ কাজ করে))
ভাসা ইনপুট কোন নান নোট হন যে maxps a,b
ঠিক কার্যকরী (a<b) ? a : b
, unordered উপর 2nd প্রতীক থেকে উপাদান পালন । সুতরাং ইনপুটটিতে কিছু NaN রয়েছে কিনা তা নির্ভর করে এমনকি কোনও শূন্য নন বিটম্যাপটি দিয়ে ফিরে আসা তার পক্ষে সম্ভব হতে পারে on
unsigned max4_sse2(__m128);
37 global max4_sse2
38 ;; Input 4x float32 in xmm0
39 ;; output: bitmap in EAX
40 ;; clobbers: xmm1, xmm2
41 max4_sse2:
42 ; cvtdq2ps xmm0, xmm0
43 00000040 660F70C8B1 pshufd xmm1, xmm0, 0b10110001 ; swap adjacent pairs
44 00000045 0F5FC8 maxps xmm1, xmm0
45
46 00000048 660F70D14E pshufd xmm2, xmm1, 0b01001110 ; swap high/low halves
47 0000004D 0F5FCA maxps xmm1, xmm2
48
49 00000050 0FC2C800 cmpeqps xmm1, xmm0 ; 0 / -1
50
51 00000054 0F50C1 movmskps eax, xmm1 ; extract the high bit of each dword
52 00000057 C3 ret
size = 0x58 - 0x40 = 24 bytes
অনুলিপি সহ এলোমেলো pshufd
এখনও আমাদের সেরা বাজি: থেকেshufps dst,src,imm8
কম অর্ধেকের জন্য ইনপুট পড়ে । এবং আমাদের উভয়বার একটি অ-ধ্বংসাত্মক অনুলিপি-এবং- বদল প্রয়োজন , সুতরাং 3-বাইট এবং / পিডি উভয়ই আউট। আমরা যদি একটি স্কেলার সর্বাধিক সংকীর্ণ হয়ে থাকি তবে আমরা সেগুলি ব্যবহার করতে পারি, তবে ইতিমধ্যে সমস্ত উপাদানগুলির মধ্যে আমাদের সর্বোচ্চ না থাকলে তুলনা করার আগে সম্প্রচারের জন্য আরও একটি নির্দেশনার দরকার পড়ে costsdst
dst
movhlps
unpckhps
সম্পর্কিত: এসএসই 4.1 একটি এক্সএমএম রেজিস্ট্রারে নূন্যতমের phminposuw
অবস্থান এবং মান খুঁজে পেতে পারে uint16_t
। আমি মনে করি না যে এটি 65535 থেকে বিয়োগ করে এটি সর্বোচ্চের জন্য ব্যবহার করতে হবে তবে এটি সর্বাধিক বাইট বা স্বাক্ষরিত পূর্ণসংখ্যার জন্য ব্যবহার করার জন্য একটি এসও উত্তর দেখুন ।