फाइंड फर्स्ट सेट: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
कंप्यूटर [[सॉफ़्टवेयर]] और हार्डवेयर में, पहला सेट (FFS) ढूंढें या पहला सेट ढूंढें | कंप्यूटर [[सॉफ़्टवेयर]] और हार्डवेयर में, पहला सेट (FFS) ढूंढें या पहला सेट ढूंढें [[बिट ऑपरेशन]] है, जिसे अहस्ताक्षरित [[ शब्द (कंप्यूटर वास्तुकला) |शब्द (कंप्यूटर वास्तुकला)]] दिया गया है,<ref group="nb" name="NB1"/>कम से कम महत्वपूर्ण बिट स्थिति से शब्द गणना में पर सेट किए गए कम से कम महत्वपूर्ण बिट के सूचकांक या स्थिति को निर्दिष्ट करता है। लगभग समतुल्य ऑपरेशन अनुगामी शून्यों (ctz) या अनुगामी शून्यों की संख्या (ntz) की गणना है, जो कम से कम महत्वपूर्ण बिट के बाद शून्य बिट्स की संख्या की गणना करता है। पूरक ऑपरेशन जो सबसे महत्वपूर्ण सेट बिट के सूचकांक या स्थिति का पता लगाता है, लॉग बेस 2 है, इसलिए इसे इसलिए कहा जाता है क्योंकि यह [[द्विआधारी लघुगणक]] की गणना करता है {{math|⌊log{{sub|2}}(x)⌋}}.<ref name="Anderson_1"/>यह अग्रणी शून्य (सीएलजेड) या अग्रणी शून्य की संख्या (एनएलजेड) की गणना करने के लिए #गुण और संबंध है, जो सबसे महत्वपूर्ण बिट से पहले शून्य बिट्स की संख्या की गणना करता है।<ref group="nb" name="NB2"/>पहले सेट को खोजने के दो सामान्य प्रकार हैं, [[POSIX]] परिभाषा जो 1 पर बिट्स का अनुक्रमण शुरू करती है,<ref name="Linux_2012_FFS3"/>यहां एफएफएस लेबल किया गया है, और वह वेरिएंट जो शून्य पर बिट्स का अनुक्रमण शुरू करता है, जो सीटीजेड के बराबर है और इसलिए उसे उस नाम से बुलाया जाएगा। | ||
अधिकांश आधुनिक सीपीयू [[ अनुदेश सेट वास्तुकला |अनुदेश सेट वास्तुकला]] इनमें से | अधिकांश आधुनिक सीपीयू [[ अनुदेश सेट वास्तुकला |अनुदेश सेट वास्तुकला]] इनमें से या अधिक को हार्डवेयर ऑपरेटर के रूप में प्रदान करते हैं; सॉफ़्टवेयर अनुकरण आम तौर पर उन सभी के लिए प्रदान किया जाता है जो उपलब्ध नहीं हैं, या तो कंपाइलर इंट्रिनिक्स के रूप में या सिस्टम लाइब्रेरीज़ में। | ||
== उदाहरण == | == उदाहरण == | ||
Line 16: | Line 16: | ||
काउंट ट्रेलिंग वन्स ऑपरेशन 3 लौटाएगा, काउंट लीडिंग वन्स ऑपरेशन 16 लौटाएगा, और फाइंड फर्स्ट जीरो ऑपरेशन ffz 4 लौटाएगा। | काउंट ट्रेलिंग वन्स ऑपरेशन 3 लौटाएगा, काउंट लीडिंग वन्स ऑपरेशन 16 लौटाएगा, और फाइंड फर्स्ट जीरो ऑपरेशन ffz 4 लौटाएगा। | ||
यदि शब्द शून्य है (कोई बिट्स सेट नहीं है), तो अग्रणी शून्यों की गिनती करें और पिछले शून्यों की गिनती करें, दोनों शब्द में बिट्स की संख्या लौटाते हैं, जबकि एफएफएस शून्य लौटाता है। लॉग बेस 2 और फाइंड फर्स्ट सेट के शून्य-आधारित कार्यान्वयन दोनों आम तौर पर शून्य शब्द के लिए | यदि शब्द शून्य है (कोई बिट्स सेट नहीं है), तो अग्रणी शून्यों की गिनती करें और पिछले शून्यों की गिनती करें, दोनों शब्द में बिट्स की संख्या लौटाते हैं, जबकि एफएफएस शून्य लौटाता है। लॉग बेस 2 और फाइंड फर्स्ट सेट के शून्य-आधारित कार्यान्वयन दोनों आम तौर पर शून्य शब्द के लिए अपरिभाषित परिणाम लौटाते हैं। | ||
== हार्डवेयर समर्थन == | == हार्डवेयर समर्थन == | ||
Line 137: | Line 137: | ||
कहाँ {{math|^}} बिटवाइज़ एक्सक्लूसिव-OR को दर्शाता है, {{math|{{pipe escape||}}}} बिटवाइज़ OR और को दर्शाता है {{math|~}} बिटवाइज़ नकार को दर्शाता है। | कहाँ {{math|^}} बिटवाइज़ एक्सक्लूसिव-OR को दर्शाता है, {{math|{{pipe escape||}}}} बिटवाइज़ OR और को दर्शाता है {{math|~}} बिटवाइज़ नकार को दर्शाता है। | ||
उलटा समस्या (दिया गया है {{math|''i''}}, | उलटा समस्या (दिया गया है {{math|''i''}}, उत्पादन करें {{math|''x''}} ऐसा है कि {{math|ctz(''x'') {{=}} ''i''}}) की गणना बाईं-शिफ्ट के साथ की जा सकती है ({{math|1 << ''i''}}). | ||
पहला सेट ढूंढें और संबंधित संचालन को | पहला सेट ढूंढें और संबंधित संचालन को छोर से शुरू करके और शब्द तक आगे बढ़ते हुए सीधे तरीके से मनमाने ढंग से बड़े [[बिट सरणी]] तक बढ़ाया जा सकता है जो कि पूर्ण-शून्य नहीं है (के लिए) {{math|ffs}}, {{math|ctz}}, {{math|clz}}) या सभी-एक नहीं (के लिए)। {{math|ffz}}, {{math|clo}}, {{math|cto}}) का सामना करना पड़ता है। ट्री डेटा संरचना जो पुनरावर्ती रूप से बिटमैप का उपयोग करके ट्रैक करती है कि कौन से शब्द गैर-शून्य हैं, इसे तेज कर सकते हैं। | ||
==सॉफ़्टवेयर अनुकरण== | ==सॉफ़्टवेयर अनुकरण== | ||
1980 के दशक के उत्तरार्ध के अधिकांश सीपीयू में एफएफएस या समकक्ष के लिए बिट ऑपरेटर होते हैं, लेकिन एआरएम-एमएक्स श्रृंखला जैसे कुछ आधुनिक सीपीयू में ऐसा नहीं होता है। एफएफएस, सीएलजेड और सीटीजेड के लिए हार्डवेयर ऑपरेटरों के बदले में, सॉफ्टवेयर उन्हें शिफ्ट, पूर्णांक अंकगणित और बिटवाइज़ ऑपरेटरों के साथ अनुकरण कर सकता है। सीपीयू की वास्तुकला और कुछ हद तक प्रोग्रामिंग भाषा के शब्दार्थ और कंपाइलर कोड पीढ़ी की गुणवत्ता के आधार पर कई दृष्टिकोण हैं। दृष्टिकोणों को शिथिल रूप से [[रैखिक खोज]] के रूप में वर्णित किया जा सकता है, [[द्विआधारी खोज]], खोज+टेबल लुकअप, डी ब्रुइज़न गुणन, फ़्लोटिंग पॉइंट रूपांतरण/प्रतिपादक अर्क, और बिट ऑपरेटर (शाखा रहित) तरीके. निष्पादन समय और भंडारण स्थान के साथ-साथ पोर्टेबिलिटी और दक्षता के बीच भी विरोधाभास है। | 1980 के दशक के उत्तरार्ध के अधिकांश सीपीयू में एफएफएस या समकक्ष के लिए बिट ऑपरेटर होते हैं, लेकिन एआरएम-एमएक्स श्रृंखला जैसे कुछ आधुनिक सीपीयू में ऐसा नहीं होता है। एफएफएस, सीएलजेड और सीटीजेड के लिए हार्डवेयर ऑपरेटरों के बदले में, सॉफ्टवेयर उन्हें शिफ्ट, पूर्णांक अंकगणित और बिटवाइज़ ऑपरेटरों के साथ अनुकरण कर सकता है। सीपीयू की वास्तुकला और कुछ हद तक प्रोग्रामिंग भाषा के शब्दार्थ और कंपाइलर कोड पीढ़ी की गुणवत्ता के आधार पर कई दृष्टिकोण हैं। दृष्टिकोणों को शिथिल रूप से [[रैखिक खोज]] के रूप में वर्णित किया जा सकता है, [[द्विआधारी खोज]], खोज+टेबल लुकअप, डी ब्रुइज़न गुणन, फ़्लोटिंग पॉइंट रूपांतरण/प्रतिपादक अर्क, और बिट ऑपरेटर (शाखा रहित) तरीके. निष्पादन समय और भंडारण स्थान के साथ-साथ पोर्टेबिलिटी और दक्षता के बीच भी विरोधाभास है। | ||
सॉफ़्टवेयर अनुकरण आमतौर पर नियतात्मक होते हैं। वे सभी इनपुट मानों के लिए | सॉफ़्टवेयर अनुकरण आमतौर पर नियतात्मक होते हैं। वे सभी इनपुट मानों के लिए परिभाषित परिणाम लौटाते हैं; विशेष रूप से, सभी शून्य बिट्स के इनपुट का परिणाम आम तौर पर एफएफएस के लिए 0 होता है, और अन्य परिचालनों के लिए ऑपरेंड की बिट लंबाई होती है। | ||
यदि किसी के पास हार्डवेयर सीएलजेड या समकक्ष है, तो सीटीजेड को बिट ऑपरेशंस के साथ कुशलतापूर्वक गणना की जा सकती है, लेकिन इसका विपरीत सच नहीं है: हार्डवेयर ऑपरेटर की अनुपस्थिति में सीएलजेड गणना करने में कुशल नहीं है। | यदि किसी के पास हार्डवेयर सीएलजेड या समकक्ष है, तो सीटीजेड को बिट ऑपरेशंस के साथ कुशलतापूर्वक गणना की जा सकती है, लेकिन इसका विपरीत सच नहीं है: हार्डवेयर ऑपरेटर की अनुपस्थिति में सीएलजेड गणना करने में कुशल नहीं है। | ||
Line 161: | Line 161: | ||
===CTZ=== | ===CTZ=== | ||
कैनोनिकल एल्गोरिदम एलएसबी से शुरू होने वाले शून्यों की गिनती करने वाला | कैनोनिकल एल्गोरिदम एलएसबी से शुरू होने वाले शून्यों की गिनती करने वाला लूप है जब तक कि 1-बिट का सामना न हो जाए:<syntaxhighlight> | ||
function ctz1 (x) | function ctz1 (x) | ||
if x = 0 return w | if x = 0 return w | ||
Line 182: | Line 182: | ||
x ← x >> n | x ← x >> n | ||
r ← r + n | r ← r + n | ||
</syntaxhighlight>पैरामीटर n निश्चित है (आमतौर पर 8) और समय-स्थान ट्रेडऑफ़ का प्रतिनिधित्व करता है। लूप पूरी तरह से [[ लूप का खुलना |लूप का खुलना]] भी हो सकता है। लेकिन | </syntaxhighlight>पैरामीटर n निश्चित है (आमतौर पर 8) और समय-स्थान ट्रेडऑफ़ का प्रतिनिधित्व करता है। लूप पूरी तरह से [[ लूप का खुलना |लूप का खुलना]] भी हो सकता है। लेकिन रैखिक लुकअप के रूप में, ऑपरेंड में बिट्स की संख्या में यह दृष्टिकोण अभी भी O(n) है। | ||
एक बाइनरी खोज कार्यान्वयन संचालन और शाखाओं की | एक बाइनरी खोज कार्यान्वयन संचालन और शाखाओं की लघुगणकीय संख्या लेता है, जैसा कि इस 32-बिट संस्करण में है:<ref name="Warren_2013_5-3"/><ref name="Warren_2013_5-4"/>इस एल्गोरिदम को तालिका द्वारा भी सहायता प्रदान की जा सकती है, जो सूचकांक के रूप में सामने आए पहले गैर-शून्य बाइट का उपयोग करके 256 प्रविष्टि लुकअप तालिका के साथ नीचे के तीन यदि कथनों को प्रतिस्थापित करती है।<syntaxhighlight> | ||
function ctz3 (x) | function ctz3 (x) | ||
if x = 0 return 32 | if x = 0 return 32 | ||
Line 198: | Line 198: | ||
x &= -x | x &= -x | ||
return w - (clz(x) + 1) | return w - (clz(x) + 1) | ||
</syntaxhighlight>32-बिट सीटीज़ के लिए | </syntaxhighlight>32-बिट सीटीज़ के लिए एल्गोरिदम न्यूनतम सही हैश फ़ंक्शन बनाने के लिए डी ब्रुइज़न अनुक्रमों का उपयोग करता है जो सभी शाखाओं को समाप्त करता है।<ref name="Leiserson_1998"/><ref name="Busch_2009"/>यह एल्गोरिदम मानता है कि गुणन के परिणाम को 32 बिट तक छोटा कर दिया गया है।<syntaxhighlight> | ||
for i from 0 to 31: table[ ( 0x077CB531 * ( 1 << i ) ) >> 27 ] ← i // table [0..31] initialized | for i from 0 to 31: table[ ( 0x077CB531 * ( 1 << i ) ) >> 27 ] ← i // table [0..31] initialized | ||
function ctz5 (x) | function ctz5 (x) | ||
Line 205: | Line 205: | ||
===कल्ज़=== | ===कल्ज़=== | ||
कैनोनिकल एल्गोरिदम एमएसबी से शुरू करके | कैनोनिकल एल्गोरिदम एमएसबी से शुरू करके समय में बिट की जांच करता है जब तक कि गैर-शून्य बिट नहीं मिल जाता, जैसा कि इस उदाहरण में दिखाया गया है। यह O(n) समय में निष्पादित होता है जहां n ऑपरेंड की बिट-लंबाई है, और सामान्य उपयोग के लिए व्यावहारिक एल्गोरिदम नहीं है।<syntaxhighlight> | ||
function clz1 (x) | function clz1 (x) | ||
if x = 0 return w | if x = 0 return w | ||
Line 214: | Line 214: | ||
r ← r + 1 | r ← r + 1 | ||
return r | return r | ||
</syntaxhighlight>पिछले लूपिंग दृष्टिकोण में सुधार | </syntaxhighlight>पिछले लूपिंग दृष्टिकोण में सुधार समय में आठ बिट्स की जांच करता है और फिर 256 (2) का उपयोग करता है<sup>8</sup>) पहले गैर-शून्य बाइट के लिए प्रविष्टि लुकअप तालिका। हालाँकि, यह दृष्टिकोण निष्पादन समय में अभी भी O(n) है।<syntaxhighlight> | ||
function clz2 (x) | function clz2 (x) | ||
if x = 0 return w | if x = 0 return w | ||
Line 233: | Line 233: | ||
if (x & 0x80000000) = 0: n ← n + 1 | if (x & 0x80000000) = 0: n ← n + 1 | ||
return n | return n | ||
</syntaxhighlight>सीएलज़ को अनुकरण करने के लिए सबसे तेज़ पोर्टेबल दृष्टिकोण बाइनरी सर्च और टेबल लुकअप का संयोजन है: | </syntaxhighlight>सीएलज़ को अनुकरण करने के लिए सबसे तेज़ पोर्टेबल दृष्टिकोण बाइनरी सर्च और टेबल लुकअप का संयोजन है: 8-बिट टेबल लुकअप (2)<sup>8</sup>=256 1-बाइट प्रविष्टियाँ) बाइनरी खोज में नीचे की 3 शाखाओं को प्रतिस्थापित कर सकती हैं। 64-बिट ऑपरेंड को अतिरिक्त शाखा की आवश्यकता होती है। बड़ी चौड़ाई वाले लुकअप का उपयोग किया जा सकता है लेकिन अधिकतम व्यावहारिक तालिका का आकार आधुनिक प्रोसेसर पर L1 डेटा कैश के आकार तक सीमित है, जो कई लोगों के लिए 32 KB है। किसी शाखा को सहेजना L1 कैश मिस की विलंबता से ऑफसेट से कहीं अधिक है। | ||
CTZ के लिए डी ब्रुइज़न गुणन के समान | CTZ के लिए डी ब्रुइज़न गुणन के समान एल्गोरिथ्म CLZ के लिए काम करता है, लेकिन सबसे महत्वपूर्ण बिट को अलग करने के बजाय, यह फॉर्म 2 के निकटतम पूर्णांक तक पूर्णांक बनाता है<sup>n</sup>−1 शिफ्ट और बिटवाइज़ ORs का उपयोग करना:<ref name="Anderson_3"/><syntaxhighlight> | ||
table[0..31] = {0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, | table[0..31] = {0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, | ||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31} | 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31} | ||
Line 264: | Line 264: | ||
==अनुप्रयोग== | ==अनुप्रयोग== | ||
सामान्यीकरण को कुशलतापूर्वक लागू करने के लिए गिनती अग्रणी शून्य (सीएलजेड) ऑपरेशन का उपयोग किया जा सकता है, जो | सामान्यीकरण को कुशलतापूर्वक लागू करने के लिए गिनती अग्रणी शून्य (सीएलजेड) ऑपरेशन का उपयोग किया जा सकता है, जो पूर्णांक को एम × 2 के रूप में एन्कोड करता है<sup>e</sup>, जहां m का ज्ञात स्थिति में सबसे महत्वपूर्ण बिट है (जैसे कि उच्चतम स्थिति)। इसके बदले में इसका उपयोग न्यूटन-रेफसन डिवीजन को लागू करने, सॉफ्टवेयर और अन्य अनुप्रयोगों में पूर्णांक से [[ तैरनेवाला स्थल |तैरनेवाला स्थल]] रूपांतरण करने के लिए किया जा सकता है।<ref name="Warren_2013_5-3"/><ref name="Sloss_2004"/> | ||
अग्रणी शून्यों की गणना करें (clz) का उपयोग पहचान के माध्यम से 32-बिट विधेय x = y (यदि सत्य है तो शून्य, यदि गलत है तो एक) की गणना करने के लिए किया जा सकता है {{tt|clz(x − y) >> 5}}, जहां >> अहस्ताक्षरित दायां बदलाव है।<ref name="Warren_2013_2-11"/>इसका उपयोग अधिक परिष्कृत बिट संचालन करने के लिए किया जा सकता है जैसे n 1 बिट्स की पहली स्ट्रिंग ढूंढना।<ref name="Warren_2013_6-2"/>इजहार {{tt|clz(x − y)1 << (16 − clz(x − 1)/2)}} न्यूटन की विधि का उपयोग करके 32-बिट पूर्णांक के वर्गमूल की गणना के लिए | अग्रणी शून्यों की गणना करें (clz) का उपयोग पहचान के माध्यम से 32-बिट विधेय x = y (यदि सत्य है तो शून्य, यदि गलत है तो एक) की गणना करने के लिए किया जा सकता है {{tt|clz(x − y) >> 5}}, जहां >> अहस्ताक्षरित दायां बदलाव है।<ref name="Warren_2013_2-11"/>इसका उपयोग अधिक परिष्कृत बिट संचालन करने के लिए किया जा सकता है जैसे n 1 बिट्स की पहली स्ट्रिंग ढूंढना।<ref name="Warren_2013_6-2"/>इजहार {{tt|clz(x − y)1 << (16 − clz(x − 1)/2)}} न्यूटन की विधि का उपयोग करके 32-बिट पूर्णांक के वर्गमूल की गणना के लिए प्रभावी प्रारंभिक अनुमान है।<ref name="Warren_2013_11-1"/>सीएलजेड कुशलतापूर्वक शून्य दमन को कार्यान्वित कर सकता है, तेज़ डेटा संपीड़न तकनीक जो पूर्णांक को गैर-शून्य बाइट्स के साथ अग्रणी शून्य बाइट्स की संख्या के रूप में एन्कोड करती है।<ref name="Schlegel_2010"/>यह समान वितरण (असतत) पूर्णांकों का सीएलजेड लेकर कुशलतापूर्वक घातीय वितरण पूर्णांक उत्पन्न कर सकता है।<ref name="Warren_2013_5-3"/> | ||
लॉग बेस 2 का उपयोग यह अनुमान लगाने के लिए किया जा सकता है कि गुणन अतिप्रवाह होगा या नहीं {{math|⌈log{{sub|2}}(xy)⌉ ≤ ⌈log{{sub|2}}(x)⌉ + ⌈log{{sub|2}}(y)⌉}}.<ref name="Warren_2013_2-12"/> | लॉग बेस 2 का उपयोग यह अनुमान लगाने के लिए किया जा सकता है कि गुणन अतिप्रवाह होगा या नहीं {{math|⌈log{{sub|2}}(xy)⌉ ≤ ⌈log{{sub|2}}(x)⌉ + ⌈log{{sub|2}}(y)⌉}}.<ref name="Warren_2013_2-12"/> | ||
गोस्पर के लूप-डिटेक्शन एल्गोरिदम को लागू करने के लिए अग्रणी शून्यों की गिनती और अनुगामी शून्यों की गिनती का | गोस्पर के लूप-डिटेक्शन एल्गोरिदम को लागू करने के लिए अग्रणी शून्यों की गिनती और अनुगामी शून्यों की गिनती का साथ उपयोग किया जा सकता है,<ref name="Gosper_1972"/>जो सीमित संसाधनों का उपयोग करके परिमित सीमा के किसी फ़ंक्शन की अवधि ज्ञात कर सकता है।<ref name="Warren_2013_5-4"/> | ||
[[बाइनरी जीसीडी एल्गोरिदम]] पिछले शून्य को हटाने में कई चक्र खर्च करता है; इसे | [[बाइनरी जीसीडी एल्गोरिदम]] पिछले शून्य को हटाने में कई चक्र खर्च करता है; इसे बदलाव के बाद शून्य के पीछे की गिनती (ctz) से बदला जा सकता है। समान लूप हेलस्टोन अनुक्रम की गणना में दिखाई देता है। | ||
[[प्राथमिकता कतार]] को लागू करने के लिए | [[प्राथमिकता कतार]] को लागू करने के लिए बिट सरणी का उपयोग किया जा सकता है। इस संदर्भ में, फाइंड फर्स्ट सेट (एफएफएस) पॉप या पुल उच्चतम प्राथमिकता वाले तत्व ऑपरेशन को कुशलतापूर्वक लागू करने में उपयोगी है। [[लिनक्स कर्नेल]] रीयल-टाइम शेड्यूलर आंतरिक रूप से उपयोग करता है <code>sched_find_first_bit()</code> इस उद्देश्य से।<ref name="Aas_2005"/> | ||
काउंट ट्रेलिंग शून्य ऑपरेशन हनोई टॉवर समस्या का | काउंट ट्रेलिंग शून्य ऑपरेशन हनोई टॉवर समस्या का सरल इष्टतम समाधान देता है: डिस्क को शून्य से क्रमांकित किया जाता है, और चाल k पर, डिस्क संख्या ctz(k) को दाईं ओर न्यूनतम संभव दूरी पर ले जाया जाता है (वापस चारों ओर चक्कर लगाते हुए) आवश्यकतानुसार छोड़ दिया गया)। यह मनमाना शब्द लेकर और चरण k पर बिट ctz(k) फ़्लिप करके [[ग्रे कोड]] भी उत्पन्न कर सकता है।<ref name="Warren_2013_5-4"/> | ||
Line 355: | Line 355: | ||
==अग्रिम पठन== | ==अग्रिम पठन== | ||
* | * {{Cite book |title=Hacker's Delight |title-link=Hacker's Delight |author-first=Henry S. |author-last=Warren, Jr. |date=2013 |orig-date=2002 |edition=2 |publisher=[[Addison Wesley]] - [[Pearson Education, Inc.]] |isbn=978-0-321-84268-8 |id=0-321-84268-5}} | ||
* | * {{cite web |author-last=Anderson |author-first=Sean Eron |title=Bit Twiddling Hacks |url=http://graphics.stanford.edu/~seander/bithacks.html |date=2005 |orig-date=1997 |publisher=[[Stanford University]] |access-date=2012-01-03 |url-status=live |archive-url=https://web.archive.org/web/20200108172348/http://graphics.stanford.edu/~seander/bithacks.html |archive-date=2020-01-08}} (NB. Lists several efficient public domain C implementations for [http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear count trailing zeros] and [http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious log base 2].) | ||
Revision as of 11:40, 19 July 2023
कंप्यूटर सॉफ़्टवेयर और हार्डवेयर में, पहला सेट (FFS) ढूंढें या पहला सेट ढूंढें बिट ऑपरेशन है, जिसे अहस्ताक्षरित शब्द (कंप्यूटर वास्तुकला) दिया गया है,[nb 1]कम से कम महत्वपूर्ण बिट स्थिति से शब्द गणना में पर सेट किए गए कम से कम महत्वपूर्ण बिट के सूचकांक या स्थिति को निर्दिष्ट करता है। लगभग समतुल्य ऑपरेशन अनुगामी शून्यों (ctz) या अनुगामी शून्यों की संख्या (ntz) की गणना है, जो कम से कम महत्वपूर्ण बिट के बाद शून्य बिट्स की संख्या की गणना करता है। पूरक ऑपरेशन जो सबसे महत्वपूर्ण सेट बिट के सूचकांक या स्थिति का पता लगाता है, लॉग बेस 2 है, इसलिए इसे इसलिए कहा जाता है क्योंकि यह द्विआधारी लघुगणक की गणना करता है ⌊log2(x)⌋.[1]यह अग्रणी शून्य (सीएलजेड) या अग्रणी शून्य की संख्या (एनएलजेड) की गणना करने के लिए #गुण और संबंध है, जो सबसे महत्वपूर्ण बिट से पहले शून्य बिट्स की संख्या की गणना करता है।[nb 2]पहले सेट को खोजने के दो सामान्य प्रकार हैं, POSIX परिभाषा जो 1 पर बिट्स का अनुक्रमण शुरू करती है,[2]यहां एफएफएस लेबल किया गया है, और वह वेरिएंट जो शून्य पर बिट्स का अनुक्रमण शुरू करता है, जो सीटीजेड के बराबर है और इसलिए उसे उस नाम से बुलाया जाएगा।
अधिकांश आधुनिक सीपीयू अनुदेश सेट वास्तुकला इनमें से या अधिक को हार्डवेयर ऑपरेटर के रूप में प्रदान करते हैं; सॉफ़्टवेयर अनुकरण आम तौर पर उन सभी के लिए प्रदान किया जाता है जो उपलब्ध नहीं हैं, या तो कंपाइलर इंट्रिनिक्स के रूप में या सिस्टम लाइब्रेरीज़ में।
उदाहरण
निम्नलिखित 32-बिट शब्द दिया गया है:
- 0000 0000 0000 0000 1000 0000 0000 1000
गिनती के पीछे शून्य ऑपरेशन 3 लौटाएगा, जबकि गिनती अग्रणी शून्य ऑपरेशन 16 लौटाएगा। गिनती अग्रणी शून्य ऑपरेशन शब्द आकार पर निर्भर करता है: यदि इस 32-बिट शब्द को 16-बिट शब्द में छोटा कर दिया गया था, तो गिनती अग्रणी शून्य शून्य वापस आएगा . पहला सेट ढूंढें ऑपरेशन 4 लौटाएगा, जो दाईं ओर से चौथी स्थिति को दर्शाता है। लॉग बेस 2 15 है।
इसी प्रकार, निम्नलिखित 32-बिट शब्द को देखते हुए, उपरोक्त शब्द का बिटवाइज़ निषेध:
- 1111 1111 1111 1111 0111 1111 1111 0111
काउंट ट्रेलिंग वन्स ऑपरेशन 3 लौटाएगा, काउंट लीडिंग वन्स ऑपरेशन 16 लौटाएगा, और फाइंड फर्स्ट जीरो ऑपरेशन ffz 4 लौटाएगा।
यदि शब्द शून्य है (कोई बिट्स सेट नहीं है), तो अग्रणी शून्यों की गिनती करें और पिछले शून्यों की गिनती करें, दोनों शब्द में बिट्स की संख्या लौटाते हैं, जबकि एफएफएस शून्य लौटाता है। लॉग बेस 2 और फाइंड फर्स्ट सेट के शून्य-आधारित कार्यान्वयन दोनों आम तौर पर शून्य शब्द के लिए अपरिभाषित परिणाम लौटाते हैं।
हार्डवेयर समर्थन
कई आर्किटेक्चर में नीचे सूचीबद्ध पहले सेट और/या संबंधित संचालन को तेजी से निष्पादित करने के लिए निर्देश सेट शामिल हैं। सबसे आम ऑपरेशन गिनती अग्रणी शून्य (सीएलजेड) है, संभवतः क्योंकि अन्य सभी ऑपरेशन इसके संदर्भ में कुशलतापूर्वक कार्यान्वित किए जा सकते हैं (#गुण और संबंध देखें)।
Platform | Mnemonic | Name | Operand widths | Description | On application to 0 |
---|---|---|---|---|---|
ARM (ARMv5T architecture and later) except Cortex-M0/M0+/M1/M23 |
clz[3] | Count Leading Zeros | 32 | clz | 32 |
ARM (ARMv8-A architecture) | clz | Count Leading Zeros | 32, 64 | clz | Operand width |
AVR32 | clz[4] | Count Leading Zeros | 32 | clz | 32 |
DEC Alpha | ctlz[5] | Count Leading Zeros | 64 | clz | 64 |
cttz[5] | Count Trailing Zeros | 64 | ctz | 64 | |
Intel 80386 and later | bsf[6] | Bit Scan Forward | 16, 32, 64 | ctz | Undefined; sets zero flag |
bsr[6] | Bit Scan Reverse | 16, 32, 64 | Log base 2 | Undefined; sets zero flag | |
x86 supporting BMI1 or ABM | lzcnt[7] | Count Leading Zeros | 16, 32, 64 | clz | Operand width; sets carry flag |
x86 supporting BMI1 | tzcnt[8] | Count Trailing Zeros | 16, 32, 64 | ctz | Operand width; sets carry flag |
Itanium | clz[9] | Count Leading Zeros | 64 | clz | 64 |
MIPS32/MIPS64 | clz[10][11] | Count Leading Zeros in Word | 32, 64 | clz | Operand width |
clo[10][11] | Count Leading Ones in Word | 32, 64 | clo | Operand width | |
Motorola 68020 and later | bfffo[12] | Find First One in Bit Field | Arbitrary | Log base 2 | Field offset + field width |
PDP-10 | jffo | Jump if Find First One | 36 | ctz | 0; no operation |
POWER/PowerPC/Power ISA | cntlz/cntlzw/cntlzd[13] | Count Leading Zeros | 32, 64 | clz | Operand width |
Power ISA 3.0 and later | cnttzw/cnttzd[14] | Count Trailing Zeros | 32, 64 | ctz | Operand width |
RISC-V ("B" Extension) (draft) | clz[15] | Count Leading Zeros | 32, 64 | clz | Operand width |
ctz[15] | Count Trailing Zeros | 32, 64 | ctz | Operand width | |
SPARC Oracle Architecture 2011 and later | lzcnt (synonym: lzd)[16] | Leading Zero Count | 64 | clz | 64 |
VAX | ffs[17] | Find First Set | 0–32 | ctz | Operand width; sets zero flag |
IBM z/Architecture | flogr[18] | Find Leftmost One | 64 | clz | 64 |
vclz[18] | Vector Count Leading Zeroes | 8, 16, 32, 64 | clz | Operand width | |
vctz[18] | Vector Count Trailing Zeroes | 8, 16, 32, 64 | ctz | Operand width |
कुछ अल्फ़ा प्लेटफ़ॉर्म पर CTLZ और CTTZ का सॉफ़्टवेयर में अनुकरण किया जाता है।
उपकरण और पुस्तकालय समर्थन
कई कंपाइलर और लाइब्रेरी विक्रेता पहले सेट और/या संबंधित संचालन को खोजने के लिए कंपाइलर इंट्रिनिक्स या लाइब्रेरी फ़ंक्शंस की आपूर्ति करते हैं, जिन्हें अक्सर उपरोक्त हार्डवेयर निर्देशों के संदर्भ में कार्यान्वित किया जाता है:
Tool/library | Name | Type | Input type(s) | Notes | On application to 0 |
---|---|---|---|---|---|
POSIX.1 compliant libc 4.3BSD libc OS X 10.3 libc[2][19] |
ffs |
Library function | int | Includes glibc. POSIX does not supply the complementary log base 2 / clz. | 0 |
FreeBSD 5.3 libc OS X 10.4 libc[19] |
ffsl fls flsl |
Library function | int, long |
fls("find last set") computes (log base 2) + 1. | 0 |
FreeBSD 7.1 libc[20] | ffsll flsll |
Library function | long long | 0 | |
GCC 3.4.0[21][22] Clang 5.x[23][24] |
__builtin_ffs[l,ll,imax] __builtin_clz[l,ll,imax] __builtin_ctz[l,ll,imax] |
Built-in functions | unsigned int, unsigned long, unsigned long long, uintmax_t |
GCC documentation considers result undefined clz and ctz on 0. | 0 (ffs) |
Visual Studio 2005 | _BitScanForward [25]_BitScanReverse [26] |
Compiler intrinsics | unsigned long, unsigned __int64 |
Separate return value to indicate zero input | Undefined |
Visual Studio 2008 | __lzcnt [27] |
Compiler intrinsic | unsigned short, unsigned int, unsigned __int64 |
Relies on hardware support for the lzcnt instruction introduced in BMI1 or ABM. | Operand width |
Visual Studio 2012 | _arm_clz [28] |
Compiler intrinsic | unsigned int | Relies on hardware support for the clz instruction introduced in the ARMv5T architecture and later. | ? |
Intel C++ Compiler | _bit_scan_forward _bit_scan_reverse [29][30] |
Compiler intrinsics | int | Undefined | |
NVIDIA CUDA[31] | __clz |
Functions | 32-bit, 64-bit | Compiles to fewer instructions on the GeForce 400 Series | 32 |
__ffs |
0 | ||||
LLVM | llvm.ctlz.* llvm.cttz.* [32] |
Intrinsic | 8, 16, 32, 64, 256 | LLVM assembly language | Operand width, if 2nd argument is 0; undefined otherwise |
GHC 7.10 (base 4.8), in Data.Bits [citation needed] |
countLeadingZeros countTrailingZeros |
Library function | FiniteBits b => b |
Haskell programming language | Operand width |
C++20 standard library, in header <bit> [33][34] |
bit_ceil bit_floor bit_width countl_zero countl_one countr_zero countr_one |
Library function | unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long |
गुण और संबंध
यदि बिट्स को 1 से शुरू करके लेबल किया गया है (जो कि इस आलेख में प्रयुक्त परंपरा है), तो अनुगामी शून्यों की गणना करें और पता लगाएं कि पहले सेट ऑपरेशन किससे संबंधित हैं ctz(x) = ffs(x) − 1 (सिवाय जब इनपुट शून्य हो)। यदि बिट्स को प्रारंभ से लेबल किया गया है 0, फिर पिछले शून्यों की गिनती करें और पता लगाएं कि पहला सेट बिल्कुल समतुल्य संचालन है। दिया गया w प्रति शब्द बिट्स, log2 से आसानी से गणना की जा सकती है clz और इसके विपरीत log2(x) = w − 1 − clz(x).
जैसा कि ऊपर दिए गए उदाहरण में दिखाया गया है, पहले शून्य ढूंढें, अग्रणी शून्य गिनें, और अनुगामी शून्य गिनें संचालन को इनपुट को अस्वीकार करके और पहले सेट ढूंढें, अग्रणी शून्य गिनें, और अनुगामी शून्य गिनें का उपयोग करके कार्यान्वित किया जा सकता है। विपरीत भी सही है।
कुशल लॉग वाले प्लेटफ़ॉर्म पर2 M68000 जैसे ऑपरेशन, ctz द्वारा गणना की जा सकती है:
- ctz(x) = log2(x & −x)
कहाँ & बिटवाइज़ AND और को दर्शाता है −x दोनों के पूरक को दर्शाता है x. इजहार x & −x न्यूनतम-महत्वपूर्ण को छोड़कर सभी को साफ़ करता है 1 बिट, ताकि सबसे अधिक- और सबसे कम-महत्वपूर्ण 1 बिट समान हैं.
एआरएम और पावरपीसी जैसे कुशल गिनती अग्रणी शून्य संचालन वाले प्लेटफार्मों पर, ffs द्वारा गणना की जा सकती है:
- ffs(x) = w − clz(x & −x).
इसके विपरीत, बिना मशीनों पर log2 या clz ऑपरेटर, clz का उपयोग करके गणना की जा सकती है ctz, यद्यपि अकुशलता से:
- clz = w − ctz(2⌈log2(x)⌉) (जिस पर निर्भर करता है ctz लौट रहा हूँ w शून्य इनपुट के लिए)
SPARC जैसे कुशल हथौड़ा चलाना वजन (जनसंख्या गणना) ऑपरेशन वाले प्लेटफार्मों पर POPC
[35][36]या Blackfin का ONES
,[37]वहाँ है:
- ctz(x) = popcount((x & −x) − 1),[38][39]या ctz(x) = popcount(~(x | −x)),
- ffs(x) = popcount(x ^ ~−x)[35]: clz = 32 − popcount(2⌈log2(x)⌉ − 1)
कहाँ ^ बिटवाइज़ एक्सक्लूसिव-OR को दर्शाता है, | बिटवाइज़ OR और को दर्शाता है ~ बिटवाइज़ नकार को दर्शाता है।
उलटा समस्या (दिया गया है i, उत्पादन करें x ऐसा है कि ctz(x) = i) की गणना बाईं-शिफ्ट के साथ की जा सकती है (1 << i).
पहला सेट ढूंढें और संबंधित संचालन को छोर से शुरू करके और शब्द तक आगे बढ़ते हुए सीधे तरीके से मनमाने ढंग से बड़े बिट सरणी तक बढ़ाया जा सकता है जो कि पूर्ण-शून्य नहीं है (के लिए) ffs, ctz, clz) या सभी-एक नहीं (के लिए)। ffz, clo, cto) का सामना करना पड़ता है। ट्री डेटा संरचना जो पुनरावर्ती रूप से बिटमैप का उपयोग करके ट्रैक करती है कि कौन से शब्द गैर-शून्य हैं, इसे तेज कर सकते हैं।
सॉफ़्टवेयर अनुकरण
1980 के दशक के उत्तरार्ध के अधिकांश सीपीयू में एफएफएस या समकक्ष के लिए बिट ऑपरेटर होते हैं, लेकिन एआरएम-एमएक्स श्रृंखला जैसे कुछ आधुनिक सीपीयू में ऐसा नहीं होता है। एफएफएस, सीएलजेड और सीटीजेड के लिए हार्डवेयर ऑपरेटरों के बदले में, सॉफ्टवेयर उन्हें शिफ्ट, पूर्णांक अंकगणित और बिटवाइज़ ऑपरेटरों के साथ अनुकरण कर सकता है। सीपीयू की वास्तुकला और कुछ हद तक प्रोग्रामिंग भाषा के शब्दार्थ और कंपाइलर कोड पीढ़ी की गुणवत्ता के आधार पर कई दृष्टिकोण हैं। दृष्टिकोणों को शिथिल रूप से रैखिक खोज के रूप में वर्णित किया जा सकता है, द्विआधारी खोज, खोज+टेबल लुकअप, डी ब्रुइज़न गुणन, फ़्लोटिंग पॉइंट रूपांतरण/प्रतिपादक अर्क, और बिट ऑपरेटर (शाखा रहित) तरीके. निष्पादन समय और भंडारण स्थान के साथ-साथ पोर्टेबिलिटी और दक्षता के बीच भी विरोधाभास है।
सॉफ़्टवेयर अनुकरण आमतौर पर नियतात्मक होते हैं। वे सभी इनपुट मानों के लिए परिभाषित परिणाम लौटाते हैं; विशेष रूप से, सभी शून्य बिट्स के इनपुट का परिणाम आम तौर पर एफएफएस के लिए 0 होता है, और अन्य परिचालनों के लिए ऑपरेंड की बिट लंबाई होती है।
यदि किसी के पास हार्डवेयर सीएलजेड या समकक्ष है, तो सीटीजेड को बिट ऑपरेशंस के साथ कुशलतापूर्वक गणना की जा सकती है, लेकिन इसका विपरीत सच नहीं है: हार्डवेयर ऑपरेटर की अनुपस्थिति में सीएलजेड गणना करने में कुशल नहीं है।
2n
कार्यक्रम 2⌈log2(x)⌉ (दो की निकटतम घात तक पूर्णांकित करें) शिफ्ट और बिटवाइज़ ओआरएस का उपयोग करके[40]इस 32-बिट उदाहरण की तरह गणना करना कुशल नहीं है और यदि हमारे पास 64-बिट या 128-बिट ऑपरेंड है तो यह और भी अधिक अक्षम है:
function pow2(x):
if x = 0 return invalid // invalid is implementation defined (not in [0,63])
x ← x - 1
for each y in {1, 2, 4, 8, 16}: x ← x | (x >> y)
return x + 1
एफएफएस
चूँकि ffs = ctz + 1 (POSIX) या ffs = ctz (अन्य कार्यान्वयन), ctz के लिए लागू एल्गोरिदम का उपयोग किया जा सकता है, जिसके परिणाम में 1 जोड़ने का संभावित अंतिम चरण होता है, और इनपुट के लिए ऑपरेंड लंबाई के बजाय 0 लौटाता है। सभी शून्य बिट्स.
CTZ
कैनोनिकल एल्गोरिदम एलएसबी से शुरू होने वाले शून्यों की गिनती करने वाला लूप है जब तक कि 1-बिट का सामना न हो जाए:
function ctz1 (x)
if x = 0 return w
t ← 1
r ← 0
while (x & t) = 0
t ← t << 1
r ← r + 1
return r
यह एल्गोरिदम O(n) समय और संचालन निष्पादित करता है, और बड़ी संख्या में सशर्त शाखाओं के कारण व्यवहार में अव्यावहारिक है। एक लुकअप तालिका अधिकांश शाखाओं को समाप्त कर सकती है:
table[0..2n-1] = ctz(i) for i in 0..2n-1
function ctz2 (x)
if x = 0 return w
r ← 0
loop
if (x & (2n-1)) ≠ 0
return r + table[x & (2n-1)]
x ← x >> n
r ← r + n
पैरामीटर n निश्चित है (आमतौर पर 8) और समय-स्थान ट्रेडऑफ़ का प्रतिनिधित्व करता है। लूप पूरी तरह से लूप का खुलना भी हो सकता है। लेकिन रैखिक लुकअप के रूप में, ऑपरेंड में बिट्स की संख्या में यह दृष्टिकोण अभी भी O(n) है। एक बाइनरी खोज कार्यान्वयन संचालन और शाखाओं की लघुगणकीय संख्या लेता है, जैसा कि इस 32-बिट संस्करण में है:[41][42]इस एल्गोरिदम को तालिका द्वारा भी सहायता प्रदान की जा सकती है, जो सूचकांक के रूप में सामने आए पहले गैर-शून्य बाइट का उपयोग करके 256 प्रविष्टि लुकअप तालिका के साथ नीचे के तीन यदि कथनों को प्रतिस्थापित करती है।
function ctz3 (x)
if x = 0 return 32
n ← 0
if (x & 0x0000FFFF) = 0: n ← n + 16, x ← x >> 16
if (x & 0x000000FF) = 0: n ← n + 8, x ← x >> 8
if (x & 0x0000000F) = 0: n ← n + 4, x ← x >> 4
if (x & 0x00000003) = 0: n ← n + 2, x ← x >> 2
if (x & 0x00000001) = 0: n ← n + 1
return n
यदि हार्डवेयर में clz ऑपरेटर है, तो ctz की गणना करने का सबसे कुशल तरीका इस प्रकार है:
function ctz4 (x)
x &= -x
return w - (clz(x) + 1)
32-बिट सीटीज़ के लिए एल्गोरिदम न्यूनतम सही हैश फ़ंक्शन बनाने के लिए डी ब्रुइज़न अनुक्रमों का उपयोग करता है जो सभी शाखाओं को समाप्त करता है।[43][44]यह एल्गोरिदम मानता है कि गुणन के परिणाम को 32 बिट तक छोटा कर दिया गया है।
for i from 0 to 31: table[ ( 0x077CB531 * ( 1 << i ) ) >> 27 ] ← i // table [0..31] initialized
function ctz5 (x)
return table[((x & -x) * 0x077CB531) >> 27]
अभिव्यक्ति (x & -x) फिर से सबसे कम महत्वपूर्ण 1 बिट को अलग करती है। तब केवल 32 संभावित शब्द हैं, जिन्हें अहस्ताक्षरित गुणन और हैश को तालिका में सही स्थिति में स्थानांतरित किया जाता है। (यह एल्गोरिदम शून्य इनपुट को संभाल नहीं पाता है।)
कल्ज़
कैनोनिकल एल्गोरिदम एमएसबी से शुरू करके समय में बिट की जांच करता है जब तक कि गैर-शून्य बिट नहीं मिल जाता, जैसा कि इस उदाहरण में दिखाया गया है। यह O(n) समय में निष्पादित होता है जहां n ऑपरेंड की बिट-लंबाई है, और सामान्य उपयोग के लिए व्यावहारिक एल्गोरिदम नहीं है।
function clz1 (x)
if x = 0 return w
t ← 1 << (w - 1)
r ← 0
while (x & t) = 0
t ← t >> 1
r ← r + 1
return r
पिछले लूपिंग दृष्टिकोण में सुधार समय में आठ बिट्स की जांच करता है और फिर 256 (2) का उपयोग करता है8) पहले गैर-शून्य बाइट के लिए प्रविष्टि लुकअप तालिका। हालाँकि, यह दृष्टिकोण निष्पादन समय में अभी भी O(n) है।
function clz2 (x)
if x = 0 return w
t ← 0xff << (w - 8)
r ← 0
while (x & t) = 0
t ← t >> 8
r ← r + 8
return r + table[x >> (w - 8 - r)]
बाइनरी खोज निष्पादन समय को घटाकर O(लॉग) कर सकती है2एन):
function clz3 (x)
if x = 0 return 32
n ← 0
if (x & 0xFFFF0000) = 0: n ← n + 16, x ← x << 16
if (x & 0xFF000000) = 0: n ← n + 8, x ← x << 8
if (x & 0xF0000000) = 0: n ← n + 4, x ← x << 4
if (x & 0xC0000000) = 0: n ← n + 2, x ← x << 2
if (x & 0x80000000) = 0: n ← n + 1
return n
सीएलज़ को अनुकरण करने के लिए सबसे तेज़ पोर्टेबल दृष्टिकोण बाइनरी सर्च और टेबल लुकअप का संयोजन है: 8-बिट टेबल लुकअप (2)8=256 1-बाइट प्रविष्टियाँ) बाइनरी खोज में नीचे की 3 शाखाओं को प्रतिस्थापित कर सकती हैं। 64-बिट ऑपरेंड को अतिरिक्त शाखा की आवश्यकता होती है। बड़ी चौड़ाई वाले लुकअप का उपयोग किया जा सकता है लेकिन अधिकतम व्यावहारिक तालिका का आकार आधुनिक प्रोसेसर पर L1 डेटा कैश के आकार तक सीमित है, जो कई लोगों के लिए 32 KB है। किसी शाखा को सहेजना L1 कैश मिस की विलंबता से ऑफसेट से कहीं अधिक है। CTZ के लिए डी ब्रुइज़न गुणन के समान एल्गोरिथ्म CLZ के लिए काम करता है, लेकिन सबसे महत्वपूर्ण बिट को अलग करने के बजाय, यह फॉर्म 2 के निकटतम पूर्णांक तक पूर्णांक बनाता हैn−1 शिफ्ट और बिटवाइज़ ORs का उपयोग करना:[45]
table[0..31] = {0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31}
function clz4 (x)
for each y in {1, 2, 4, 8, 16}: x ← x | (x >> y)
return table[((x * 0x07C4ACDD) >> 27) % 32]
गहरे पाइपलाइन वाले प्रोसेसर के लिए, जैसे प्रेस्कॉट और बाद के इंटेल प्रोसेसर, गलत पूर्वानुमानित शाखाओं के लिए पाइपलाइन फ्लश से बचने के लिए शाखाओं को बिटवाइज़ AND और OR ऑपरेटरों (भले ही कई और निर्देशों की आवश्यकता होती है) द्वारा प्रतिस्थापित करना तेज़ हो सकता है (और इस प्रकार की शाखाएं हैं) स्वाभाविक रूप से अप्रत्याशित):
function clz5 (x)
r = (x > 0xFFFF) << 4; x >>= r;
q = (x > 0xFF ) << 3; x >>= q; r |= q;
q = (x > 0xF ) << 2; x >>= q; r |= q;
q = (x > 0x3 ) << 1; x >>= q; r |= q;
r |= (x >> 1);
return r;
उन प्लेटफार्मों पर जो पूर्णांकों को फ़्लोटिंग पॉइंट में हार्डवेयर रूपांतरण प्रदान करते हैं, अग्रणी शून्य की गिनती की गणना करने के लिए घातांक फ़ील्ड को स्थिरांक से निकाला और घटाया जा सकता है। पूर्णांकन त्रुटियों को ध्यान में रखते हुए सुधार की आवश्यकता है।[41][46]फ़्लोटिंग पॉइंट रूपांतरण में पर्याप्त विलंबता हो सकती है। यह विधि अत्यधिक गैर-पोर्टेबल है और आमतौर पर इसकी अनुशंसा नहीं की जाती है।
int x;
int r;
union { unsigned int u[2]; double d; } t;
t.u[LE] = 0x43300000; // LE is 1 for little-endian
t.u[!LE] = x;
t.d -= 4503599627370496.0;
r = (t.u[LE] >> 20) - 0x3FF; // log2
r++; // CLZ
अनुप्रयोग
सामान्यीकरण को कुशलतापूर्वक लागू करने के लिए गिनती अग्रणी शून्य (सीएलजेड) ऑपरेशन का उपयोग किया जा सकता है, जो पूर्णांक को एम × 2 के रूप में एन्कोड करता हैe, जहां m का ज्ञात स्थिति में सबसे महत्वपूर्ण बिट है (जैसे कि उच्चतम स्थिति)। इसके बदले में इसका उपयोग न्यूटन-रेफसन डिवीजन को लागू करने, सॉफ्टवेयर और अन्य अनुप्रयोगों में पूर्णांक से तैरनेवाला स्थल रूपांतरण करने के लिए किया जा सकता है।[41][47]
अग्रणी शून्यों की गणना करें (clz) का उपयोग पहचान के माध्यम से 32-बिट विधेय x = y (यदि सत्य है तो शून्य, यदि गलत है तो एक) की गणना करने के लिए किया जा सकता है clz(x − y) >> 5, जहां >> अहस्ताक्षरित दायां बदलाव है।[48]इसका उपयोग अधिक परिष्कृत बिट संचालन करने के लिए किया जा सकता है जैसे n 1 बिट्स की पहली स्ट्रिंग ढूंढना।[49]इजहार clz(x − y)1 << (16 − clz(x − 1)/2) न्यूटन की विधि का उपयोग करके 32-बिट पूर्णांक के वर्गमूल की गणना के लिए प्रभावी प्रारंभिक अनुमान है।[50]सीएलजेड कुशलतापूर्वक शून्य दमन को कार्यान्वित कर सकता है, तेज़ डेटा संपीड़न तकनीक जो पूर्णांक को गैर-शून्य बाइट्स के साथ अग्रणी शून्य बाइट्स की संख्या के रूप में एन्कोड करती है।[51]यह समान वितरण (असतत) पूर्णांकों का सीएलजेड लेकर कुशलतापूर्वक घातीय वितरण पूर्णांक उत्पन्न कर सकता है।[41]
लॉग बेस 2 का उपयोग यह अनुमान लगाने के लिए किया जा सकता है कि गुणन अतिप्रवाह होगा या नहीं ⌈log2(xy)⌉ ≤ ⌈log2(x)⌉ + ⌈log2(y)⌉.[52]
गोस्पर के लूप-डिटेक्शन एल्गोरिदम को लागू करने के लिए अग्रणी शून्यों की गिनती और अनुगामी शून्यों की गिनती का साथ उपयोग किया जा सकता है,[53]जो सीमित संसाधनों का उपयोग करके परिमित सीमा के किसी फ़ंक्शन की अवधि ज्ञात कर सकता है।[42]
बाइनरी जीसीडी एल्गोरिदम पिछले शून्य को हटाने में कई चक्र खर्च करता है; इसे बदलाव के बाद शून्य के पीछे की गिनती (ctz) से बदला जा सकता है। समान लूप हेलस्टोन अनुक्रम की गणना में दिखाई देता है।
प्राथमिकता कतार को लागू करने के लिए बिट सरणी का उपयोग किया जा सकता है। इस संदर्भ में, फाइंड फर्स्ट सेट (एफएफएस) पॉप या पुल उच्चतम प्राथमिकता वाले तत्व ऑपरेशन को कुशलतापूर्वक लागू करने में उपयोगी है। लिनक्स कर्नेल रीयल-टाइम शेड्यूलर आंतरिक रूप से उपयोग करता है sched_find_first_bit()
इस उद्देश्य से।[54]
काउंट ट्रेलिंग शून्य ऑपरेशन हनोई टॉवर समस्या का सरल इष्टतम समाधान देता है: डिस्क को शून्य से क्रमांकित किया जाता है, और चाल k पर, डिस्क संख्या ctz(k) को दाईं ओर न्यूनतम संभव दूरी पर ले जाया जाता है (वापस चारों ओर चक्कर लगाते हुए) आवश्यकतानुसार छोड़ दिया गया)। यह मनमाना शब्द लेकर और चरण k पर बिट ctz(k) फ़्लिप करके ग्रे कोड भी उत्पन्न कर सकता है।[42]
यह भी देखें
- इंटेल और एएमडी x86-आधारित प्रोसेसर के लिए बिट हेरफेर अनुदेश सेट (बीएमआई)।
- शून्य से पीछे चल रहा है
- मुख्य शून्य
- अनुगामी अंक
- अग्रणी अंक
टिप्पणियाँ
- ↑ Using bit operations on other than an unsigned machine word may yield undefined results.
- ↑ These four operations also have (much less common) negated versions:
- find first zero (ffz), which identifies the index of the least significant zero bit;
- count trailing ones, which counts the number of one bits following the least significant zero bit.
- count leading ones, which counts the number of one bits preceding the most significant zero bit;
- find the index of the most significant zero bit, which is an inverted version of the binary logarithm.
संदर्भ
- ↑ Anderson. Find the log base 2 of an integer with the MSB N set in O(N) operations (the obvious way).
- ↑ 2.0 2.1 "FFS(3)". Linux Programmer's Manual. The Linux Kernel Archives. Retrieved 2012-01-02.
- ↑ "ARM Instruction Reference > ARM general data processing instructions > CLZ". ARM Developer Suite Assembler Guide. ARM. Retrieved 2012-01-03.
- ↑ "AVR32 Architecture Document" (PDF) (CORP072610 ed.). Atmel Corporation. 2011. 32000D–04/201. Archived from the original (PDF) on 2017-10-25. Retrieved 2016-10-22.
- ↑ 5.0 5.1 Alpha Architecture Reference Manual (PDF). Compaq. 2002. pp. 4-32, 4-34.
- ↑ 6.0 6.1 Intel 64 and IA-32 Architectures Software Developer Manual. Vol. 2A. Intel. pp. 3-92–3-97. Order number 325383.
- ↑ AMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions (PDF). Vol. 3. Advanced Micro Devices (AMD). 2011. pp. 204–205. Publication No. 24594.
- ↑ "AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions" (PDF). AMD64 Technology (Version 3.28 ed.). Advanced Micro Devices (AMD). September 2019 [2013]. Publication No. 24594. Archived (PDF) from the original on 2019-09-30. Retrieved 2014-01-02.
- ↑ Intel Itanium Architecture Software Developer's Manual. Volume 3: Intel Itanium Instruction Set. Vol. 3. Intel. 2010. pp. 3:38. Archived from the original on 2019-06-26.
- ↑ 10.0 10.1 MIPS Architecture For Programmers. Volume II-A: The MIPS32 Instruction Set (Revision 3.02 ed.). MIPS Technologies. 2011. pp. 101–102.
- ↑ 11.0 11.1 MIPS Architecture For Programmers. Volume II-A: The MIPS64 Instruction Set (Revision 3.02 ed.). MIPS Technologies. 2011. pp. 105, 107, 122, 123.
- ↑ M68000 Family Programmer's Reference Manual (Includes CPU32 Instructions) (PDF) (revision 1 ed.). Motorola. 1992. pp. 4-43–4-45. M68000PRM/AD. Archived from the original (PDF) on 2019-12-08.
- ↑ Frey, Brad. "Chapter 3.3.11 Fixed-Point Logical Instructions". PowerPC Architecture Book (Version 2.02 ed.). IBM. p. 70.
- ↑ "Chapter 3.3.13 Fixed-Point Logical Instructions - Chapter 3.3.13.1 64-bit Fixed-Point Logical Instructions". Power ISA Version 3.0B. IBM. pp. 95, 98.
- ↑ 15.0 15.1 Wolf, Clifford (2019-03-22). "RISC-V "B" Bit Manipulation Extension for RISC-V" (PDF). Github (Draft) (v0.37 ed.). Retrieved 2020-01-09.
- ↑ Oracle SPARC Architecture 2011. Oracle. 2011.
- ↑ VAX Architecture Reference Manual (PDF). Digital Equipment Corporation (DEC). 1987. pp. 70–71. Archived (PDF) from the original on 2019-09-29. Retrieved 2020-01-09.
- ↑ 18.0 18.1 18.2 "Chapter 22. Vector Integer Instructions". IBM z/Architecture Principles of Operation (PDF) (Eleventh ed.). IBM. March 2015. pp. 7-219–22-10. SA22-7832-10. Retrieved 2020-01-10.
- ↑ 19.0 19.1 "FFS(3)". Mac OS X Developer Library. Apple, Inc. 1994-04-19. Retrieved 2012-01-04.
- ↑ "FFS(3)". FreeBSD Library Functions Manual. The FreeBSD Project. Retrieved 2012-01-04.
- ↑ "Other built-in functions provided by GCC". Using the GNU Compiler Collection (GCC). Free Software Foundation, Inc. Retrieved 2015-11-14.
- ↑ "GCC 3.4.0 ChangeLog". GCC 3.4.0. Free Software Foundation, Inc. Retrieved 2015-11-14.
- ↑ "Clang Language Extensions - chapter Builtin Functions". The Clang Team. Retrieved 2017-04-09.
Clang supports a number of builtin library functions with the same syntax as GCC
- ↑ "Source code of Clang". LLVM Team, University of Illinois at Urbana-Champaign. Retrieved 2017-04-09.
- ↑ "_BitScanForward, _BitScanForward64". Visual Studio 2008: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 2018-05-21.
- ↑ "_BitScanReverse, _BitScanReverse64". Visual Studio 2008: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 2018-05-21.
- ↑ "__lzcnt16, __lzcnt, __lzcnt64". Visual Studio 2008: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 2012-01-03.
- ↑ "ARM intrinsics". Visual Studio 2012: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 2022-05-09.
- ↑ "Intel Intrinsics Guide". Intel. Retrieved 2020-04-03.
- ↑ Intel C++ Compiler for Linux Intrinsics Reference. Intel. 2006. p. 21.
- ↑ NVIDIA CUDA Programming Guide (PDF) (Version 3.0 ed.). NVIDIA. 2010. p. 92.
- ↑ "'llvm.ctlz.*' Intrinsic, 'llvm.cttz.*' Intrinsic". LLVM Language Reference Manual. The LLVM Compiler Infrastructure. Retrieved 2016-02-23.
- ↑ Smith, Richard (2020-04-01). N4861 Working Draft, Standard for Programming Language C++ (PDF). ISO/IEC. pp. 1150–1153. Retrieved 25 May 2020.
- ↑ "Standard library header <bit>". cppreference.com. Retrieved 25 May 2020.
- ↑ 35.0 35.1 SPARC International, Inc. (1992). "A.41: Population Count. Programming Note" (PDF). The SPARC architecture manual: version 8 (Version 8 ed.). Englewood Cliffs, New Jersey, USA: Prentice Hall. pp. 231. ISBN 978-0-13-825001-0.
- ↑ Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.). Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8. 0-321-84268-5.
- ↑ Blackfin Instruction Set Reference (Preliminary ed.). Analog Devices. 2001. pp. 8–24. Part Number 82-000410-14.
- ↑ Dietz, Henry Gordon. "The Aggregate Magic Algorithms". University of Kentucky. Archived from the original on 2019-10-31.
- ↑ Isenberg, Gerd (2019-11-03) [2012]. "BitScanProtected". Chess Programming Wiki (CPW). Archived from the original on 2020-01-09. Retrieved 2020-01-09.
- ↑ Anderson. Round up to the next highest power of 2.
- ↑ 41.0 41.1 41.2 41.3 Warren. Chapter 5-3: Counting Leading 0's.
- ↑ 42.0 42.1 42.2 Warren. Chapter 5-4: Counting Trailing 0's.
- ↑ Leiserson, Charles E.; Prokop, Harald; Randall, Keith H. (1998-07-07). "Using de Bruijn Sequences to Index a 1 in a Computer Word" (PDF). MIT Laboratory for Computer Science, Cambridge, MA, USA. Archived (PDF) from the original on 2020-01-09. Retrieved 2020-01-09.
- ↑ Busch, Philip (2009-03-01) [2009-02-21]. "Computing Trailing Zeros HOWTO" (PDF). Archived (PDF) from the original on 2016-08-01. Retrieved 2020-01-09.
- ↑ Anderson. Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup.
- ↑ Anderson. Find the integer log base 2 of an integer with a 64-bit IEEE float.
- ↑ Sloss, Andrew N.; Symes, Dominic; Wright, Chris (2004). ARM system developer's guide designing and optimizing system software (1 ed.). San Francisco, CA, USA: Morgan Kaufmann. pp. 212–213. ISBN 978-1-55860-874-0.
- ↑ Warren. Chapter 2-11: Comparison Predicates.
- ↑ Warren. Chapter 6-2: Find First String of 1-Bits of a Given Length.
- ↑ Warren. Chapter 11-1: Integer Square Root.
- ↑ Schlegel, Benjamin; Gemulla, Rainer; Lehner, Wolfgang [in Deutsch] (June 2010). Fast integer compression using SIMD instructions. pp. 34–40. CiteSeerX 10.1.1.230.6379. doi:10.1145/1869389.1869394. ISBN 978-1-45030189-3.
{{cite book}}
:|journal=
ignored (help) - ↑ Warren. Chapter 2-12: Overflow Detection.
- ↑ Gosper, Bill (April 1995) [1972-02-29]. Baker, Henry Givens Jr. (ed.). "Loop detector". HAKMEM (retyped & converted ed.). Cambridge, Massachusetts, USA: Artificial Intelligence Laboratory, Massachusetts Institute of Technology (MIT). AI Memo 239 Item 132. Archived from the original on 2019-10-08. Retrieved 2020-01-09.
- ↑ Aas, Josh (2005-02-17). Understanding the Linux 2.6.8.1 CPU Scheduler (PDF). Silicon Graphics, Inc. (SGI). p. 19. Archived (PDF) from the original on 2017-05-19. Retrieved 2020-01-09.
अग्रिम पठन
- Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.). Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8. 0-321-84268-5.
- Anderson, Sean Eron (2005) [1997]. "Bit Twiddling Hacks". Stanford University. Archived from the original on 2020-01-08. Retrieved 2012-01-03. (NB. Lists several efficient public domain C implementations for count trailing zeros and log base 2.)
बाहरी संबंध
- Intel Intrinsics Guide
- Chess Programming Wiki: BitScan: A detailed explanation of a number of implementation methods for ffs (called LS1B) and log base 2 (called MS1B).