आधुनिक सीपीयू में कोई `नंद` निर्देश क्यों नहीं है?


52

X86 डिजाइनरों (या अन्य सीपीयू आर्किटेक्चर के साथ) ने इसे शामिल नहीं करने का फैसला क्यों किया? यह एक लॉजिक गेट है जिसका उपयोग अन्य लॉजिक गेट बनाने के लिए किया जा सकता है, इस प्रकार यह एक निर्देश के रूप में तेज़ है। जंजीरों notऔर andनिर्देशों के बजाय (दोनों से निर्मित nand), कोई nandनिर्देश क्यों है ?।


20
नंद अनुदेश के लिए आपके पास क्या उपयोग है? संभवतः x86 डिजाइनरों को कभी नहीं मिला
प्लाज़्माएच

16
एआरएम का BICनिर्देश है, जो है a & ~b। आर्म थम्ब -2 का ORNनिर्देश है ~(a | b)। एआरएम बहुत आधुनिक है। सीपीयू अनुदेश सेट में एक निर्देश एनकोडिंग इसकी लागत है। तो केवल सबसे "उपयोगी" वाले लोग आईएसए में अपना रास्ता बना रहे हैं।
यूजीन श।

24
@ अमुमु हम ~(((a << 1) | (b >> 1)) | 0x55555555)निर्देश भी दे सकते थे। उद्देश्य इतना होगा कि ~(((a << 1) | (b >> 1)) | 0x55555555)6. के बजाय एक ही निर्देश में अनुवाद किया जा सकता है, तो क्यों नहीं?
user253751

11
@ अमुमु: यह एक usecase नहीं है, और इसके ~ नहीं भी। एक usecase एक सम्मोहक कारण है कि क्यों निर्देश उपयोगी है, और जहां इसे लागू किया जा सकता है। आपका तर्क यह कहने जैसा है कि "निर्देश होना चाहिए इसलिए इसका उपयोग किया जा सकता है" लेकिन सवाल यह है कि "इसके लिए इसका क्या उपयोग करना है, यह इतना महत्वपूर्ण है कि संसाधनों को खर्च करने के लिए यह उपयोगी है"।
प्लाज्माह

4
मैं 45 साल से प्रोग्रामिंग कर रहा हूं, कुछ कंपाइलर लिखे हैं, और कुछ अजीब लॉजिकल ऑपरेटर्स का उपयोग किया है जब छोटा सा भूत जैसे उपलब्ध है, लेकिन मुझे कभी भी एनएंड ऑपरेटर या निर्देश के लिए उपयोग नहीं किया गया है।
user207421

जवाबों:


62

http://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.alangref/idalangref_nand_nd_instrs.htm : POWER के पास NAND है।

लेकिन आम तौर पर आधुनिक सीपीयू को कंपाइलरों द्वारा स्वचालित कोड पीढ़ी से मिलान करने के लिए बनाया जाता है, और बिटवाइंड नंद को शायद ही कभी बुलाया जाता है। बिटक्वाइंड और OR डेटा संरचनाओं में बिटफिल्ड के हेरफेर के लिए अधिक बार उपयोग किया जाता है। वास्तव में, SSE के पास NAND नहीं बल्कि AND-NOT है।

डिकोड लॉजिक में हर निर्देश की लागत होती है और एक ऐसा ओपोड का उपभोग करता है जिसका उपयोग किसी और चीज के लिए किया जा सकता है। विशेष रूप से x86 जैसे चर-लंबाई के एन्कोडिंग में, आप लघु ऑपकोड से बाहर निकल सकते हैं और लंबे समय तक उपयोग करना पड़ता है, जो संभावित रूप से सभी कोड को धीमा कर देता है।


5
बिट्स को बिट-सेट चर में बंद करने के लिए आमतौर पर @supercat और NOT का उपयोग किया जाता है। जैसेif(windowType & ~WINDOW_RESIZABLE) { ... do stuff for variable-sized windows ... }
आदिब

2
@ सादीब: यूप। "और-नहीं" की एक दिलचस्प विशेषता यह है कि "बिटवाइज़ न" ऑपरेटर [~] के विपरीत परिणाम का आकार मायने नहीं रखेगा। यदि fooएक uint64_t है, तो बयान foo &= ~something;कभी-कभी अधिक बिट्स को स्पष्ट कर सकता है, लेकिन यदि कोई &~=ऑपरेटर होता तो ऐसी समस्याओं से बचा जा सकता था।
सुपरकैट

6
@adib यदि WINDOW_RESIZABLEएक स्थिर है, तो एक आशावादी ~WINDOW_RESIZABLEको संकलन समय पर मूल्यांकन करना चाहिए , इसलिए यह सिर्फ एक और रन समय पर है।
एलेफ़ेज़रो

4
@MarkRansom: नहीं, कारण और प्रभाव कंप्यूटिंग इतिहास से पूरी तरह से सही है। मानव विधानसभा प्रोग्रामर के बजाय संकलक के लिए अनुकूलित सीपीयू को डिजाइन करने की यह घटना आरआईएससी आंदोलन का हिस्सा थी (हालांकि, आरआईएससी आंदोलन खुद उस पहलू से व्यापक है)। कंपाइलरों के लिए डिज़ाइन किए गए सीपीयू में एआरएम और एटमेल एवीआर शामिल हैं। 90 के दशक के अंत और 00 के शुरुआती दिनों में लोगों ने सीपीयू निर्देश सेटों को डिजाइन करने के लिए संकलक लेखकों और ओएस प्रोग्रामर को काम पर रखा था
स्लीबेटमैन

3
इन दिनों रैम एक्सेस की तुलना में रजिस्टर-टू-रजिस्टर ऑपरेशन अनिवार्य रूप से मुफ्त हैं। निरर्थक निर्देशों को लागू करने से सीपीयू में सिलिकॉन अचल संपत्ति की लागत होती है। इसलिए आमतौर पर बिटवाइज़-ओआर और बिटवाइज़-एंड का सिर्फ एक रूप होगा क्योंकि बिटवाइज़-सप्लीमेंट रजिस्टर-रजिस्टर ऑपरेशन को जोड़ने से शायद ही कभी कुछ धीमा होगा।
nigel222

31

ऐसे एएलयू कार्यों की लागत है

1) तर्क जो कार्य स्वयं करता है

2) चयनकर्ता जो इस फ़ंक्शन के परिणाम को अन्य ALU फ़ंक्शंस से बाहर के बजाय चुनता है

3) अनुदेश सेट में यह विकल्प होने की लागत (और कुछ अन्य उपयोगी कार्य नहीं होने)

मैं आपसे सहमत हूं कि 1) लागत बहुत कम है। 2) और 3) लागत हालांकि समारोह से लगभग स्वतंत्र है। मुझे लगता है कि इस मामले में 3) लागत (अनुदेश में रखे गए बिट्स) इस विशिष्ट निर्देश के न होने का कारण थे। एक अनुदेश में बिट्स एक सीपीयू / वास्तुकला डिजाइनर के लिए एक बहुत ही दुर्लभ संसाधन हैं।


29

इसे घुमाएँ - पहले देखें कि नंद हार्डवेयर लॉजिक डिज़ाइन में लोकप्रिय क्यों थे - इसमें कई उपयोगी गुण हैं। फिर पूछें कि क्या वे गुण अभी भी एक सीपीयू निर्देश में लागू होते हैं ...

टीएल / डीआर - वे नहीं करते हैं, इसलिए इसका उपयोग करने के लिए कोई नकारात्मक पहलू नहीं है, या इसके बजाय।

नंद लॉजिक को हार्ड करने का सबसे बड़ा फायदा एक सर्किट के इनपुट और आउटपुट के बीच लॉजिक लेवल (ट्रांजिस्टर स्टेज) की संख्या को कम करके हासिल किया गया। सीपीयू में, घड़ी की गति को और अधिक जटिल ऑपरेशनों की गति के अलावा निर्धारित किया जाता है, इसलिए AND ऑपरेशन को तेज करने से आप घड़ी की दर को बढ़ा नहीं पाएंगे।

और जितनी बार आपको अन्य निर्देशों को संयोजित करने की आवश्यकता होती है, वह गायब हो जाता है - पर्याप्त है ताकि नंद वास्तव में इंस्ट्रक्शन सेट में अपनी जगह अर्जित न करें।


1
ऐसे मामलों में जहां इनपुट अलगाव की आवश्यकता नहीं होती है, हार्डवेयर में "और नहीं" बहुत सस्ता लगता है। 1977 में वापस मैंने अपने माता-पिता के ट्रेलर के लिए एक "XOR" फंक्शन [लेफ्ट लैम्प == xor (लेफ्ट सिग्नल, ब्रेक) करने के लिए प्रति लाइट दो डायोड का उपयोग करके टर्न-सिग्नल कंट्रोलर डिज़ाइन किया; सही दीपक == xor (सही संकेत, ब्रेक)], अनिवार्य रूप से प्रत्येक प्रकाश के लिए तार- oring दो और नहीं कार्य करता है। मैंने एलएसआई डिज़ाइन में इस्तेमाल की गई ऐसी ट्रिक्स नहीं देखी हैं, लेकिन मुझे लगता है कि टीटीएल या एनएमओएस में, ऐसे मामलों में जो किसी इनपुट को फीड करते हैं, पर्याप्त ड्राइव क्षमता को बढ़ाते हैं, इस तरह के ट्रिक्स सर्किट्री को बचा सकते हैं।
सुपरकैट

12

मैं ब्रायन के साथ यहाँ सहमत होना चाहता हूँ, और Wouter और pjc50।

मैं यह भी जोड़ना चाहूंगा कि सामान्य प्रयोजन, विशेष रूप से CISC, प्रोसेसर, निर्देशों में सभी समान थ्रूपुट नहीं हैं - एक जटिल ऑपरेशन बस अधिक चक्र ले सकता है जो एक आसान है।

X86 पर विचार करें: AND(जो एक "और" ऑपरेशन है) शायद बहुत तेज है। उसी के लिए जाता है NOT। आइए जरा असावधानी से देखें:

इनपुट कोड:

#include <immintrin.h>
#include <stdint.h>

__m512i nand512(__m512i a, __m512i b){return ~(a&b);}
__m256i nand256(__m256i a, __m256i b){return ~(a&b);}
__m128i nand128(__m128i a, __m128i b){return ~(a&b);}
uint64_t nand64(uint64_t a, uint64_t b){return ~(a&b);}
uint32_t nand32(uint32_t a, uint32_t b){return ~(a&b);}
uint16_t nand16(uint16_t a, uint16_t b){return ~(a&b);}
uint8_t nand8(uint8_t a, uint8_t b){return ~(a&b);}

विधानसभा का निर्माण करने की कमान:

gcc -O3 -c -S  -mavx512f test.c

आउटपुट असेंबली (छोटा):

    .file   "test.c"
nand512:
.LFB4591:
    .cfi_startproc
    vpandq  %zmm1, %zmm0, %zmm0
    vpternlogd  $0xFF, %zmm1, %zmm1, %zmm1
    vpxorq  %zmm1, %zmm0, %zmm0
    ret
    .cfi_endproc
nand256:
.LFB4592:
    .cfi_startproc
    vpand   %ymm1, %ymm0, %ymm0
    vpcmpeqd    %ymm1, %ymm1, %ymm1
    vpxor   %ymm1, %ymm0, %ymm0
    ret
    .cfi_endproc
nand128:
.LFB4593:
    .cfi_startproc
    vpand   %xmm1, %xmm0, %xmm0
    vpcmpeqd    %xmm1, %xmm1, %xmm1
    vpxor   %xmm1, %xmm0, %xmm0
    ret
    .cfi_endproc
nand64:
.LFB4594:
    .cfi_startproc
    movq    %rdi, %rax
    andq    %rsi, %rax
    notq    %rax
    ret
    .cfi_endproc
nand32:
.LFB4595:
    .cfi_startproc
    movl    %edi, %eax
    andl    %esi, %eax
    notl    %eax
    ret
    .cfi_endproc
nand16:
.LFB4596:
    .cfi_startproc
    andl    %esi, %edi
    movl    %edi, %eax
    notl    %eax
    ret
    .cfi_endproc
nand8:
.LFB4597:
    .cfi_startproc
    andl    %esi, %edi
    movl    %edi, %eax
    notl    %eax
    ret
    .cfi_endproc

जैसा कि आप देख सकते हैं, उप-64-आकार के डेटा प्रकारों के लिए, चीजों को बस सभी के रूप में लंबे समय तक संभाला जाता है (इसलिए एल और एल नहीं ), क्योंकि यह मेरे संकलक की "मूल" बिटवर्क है, जैसा कि ऐसा लगता है।

तथ्य यह है कि movबीच में s है केवल इस तथ्य के कारण है कि eaxरजिस्टर है जिसमें फ़ंक्शन का रिटर्न मान शामिल है। आम तौर पर, आप ediपरिणाम के साथ गणना करने के लिए सामान्य उद्देश्य रजिस्टर में गणना करेंगे।

64 बिट्स के लिए, यह समान है - बस "क्वाड" (इसलिए, अनुगामी q) शब्दों के साथ, और rax/ के rsiबजाय eax/ edi

ऐसा लगता है कि 128 बिट ऑपरेंड और बड़े के लिए, इंटेल ने "नहीं" ऑपरेशन को लागू करने की परवाह नहीं की; इसके बजाय, कंपाइलर एक ऑल- 1रजिस्टर (खुद के साथ रजिस्टर की स्व-तुलना, vdcmpeqdनिर्देश के साथ रजिस्टर में संग्रहीत ) का उत्पादन करता है, और xorवह है।

संक्षेप में: कई प्राथमिक निर्देशों के साथ एक जटिल ऑपरेशन को लागू करने से, आप आवश्यक रूप से ऑपरेशन को धीमा नहीं करते हैं - बस एक निर्देश होने का कोई लाभ नहीं है जो कई निर्देशों का काम करता है यदि यह तेज नहीं है।


10

सबसे पहले बिटवाइज़ और लॉजिकल ऑपरेशंस को भ्रमित न करें।

बिटवाइज ऑपरेशंस का इस्तेमाल आमतौर पर बिटफिल्ड में बिट्स सेट / क्लियर / चेक करने के लिए किया जाता है। इनमें से किसी भी ऑपरेशन के लिए नंद की आवश्यकता होती है ("और नहीं", जिसे "बिट क्लियर" के रूप में भी जाना जाता है) अधिक उपयोगी है।

अधिकांश आधुनिक प्रोग्रामिंग भाषाओं में तार्किक संचालन का मूल्यांकन शॉर्ट-सर्किट लॉजिक का उपयोग करके किया जाता है। इसलिए आमतौर पर उन्हें लागू करने के लिए एक शाखा-आधारित दृष्टिकोण की आवश्यकता होती है। यहां तक ​​कि जब कंपाइलर यह निर्धारित कर सकता है कि शॉर्ट-सर्किट बनाम पूर्ण मूल्यांकन से प्रोग्राम के व्यवहार पर कोई फर्क नहीं पड़ता है, तो तार्किक ऑपरेशंस के लिए ऑपरेंड आमतौर पर बिटवाइज़ एएसएम ऑपरेशन का उपयोग करके अभिव्यक्ति को लागू करने के लिए सुविधाजनक रूप में नहीं होता है।


10

NAND को अक्सर सीधे लागू नहीं किया जाता है क्योंकि AND निर्देश स्पष्ट रूप से आपको NAND स्थिति पर कूदने की सुविधा देता है।

सीपीयू में तार्किक ऑपरेशन करना अक्सर बिट्स को एक फ्लैग रजिस्टर में सेट करता है।

अधिकांश ध्वज रजिस्टरों में एक शून्य ध्वज होता है। शून्य ध्वज सेट किया जाता है यदि तार्किक ऑपरेशन का परिणाम शून्य होता है, और अन्यथा साफ़ किया जाता है।

अधिकांश आधुनिक सीपीयू में एक जंप इंस्ट्रक्शन होता है जो शून्य ध्वज सेट होने पर कूदता है। उनके पास एक आइसट्रक्शन भी है जो शून्य ध्वज सेट नहीं होने पर कूदता है।

और और नंद पूरक हैं। यदि एक और ऑपरेशन का परिणाम शून्य है, तो एक NAND ऑपरेशन का परिणाम 1 है, और इसके विपरीत।

इसलिए यदि आप चाहते हैं कि ओ.टी. जंप करें यदि दो मानों का NAND सही है, तो केवल AND ऑपरेशन करें, और शून्य ध्वज सेट होने पर कूदें।

इसलिए यदि आप ओट जंप चाहते हैं, यदि दो मानों का नंद झूठा है, तो सिर्फ AND ऑपरेशन करें, और शून्य ध्वज स्पष्ट होने पर कूदें।


वास्तव में - सशर्त कूद अनुदेश का विकल्प आपको व्यक्तिगत रूप से प्रत्येक विकल्प के लिए उस विकल्प को लागू करने के बिना, पूरे वर्ग संचालन के लिए inverting और गैर-inverting तर्क का विकल्प देता है।
क्रिस स्ट्रैटन

यह सबसे अच्छा जवाब होना चाहिए था। शून्य फ्लैग ऑपरेशंस तार्किक संचालन के लिए NAND को बेहतर बनाता है क्योंकि AND + JNZ और AND + JZ क्रमशः छोटे सर्कुलेटेड / लॉजिकल और NAND हैं, दोनों एक ही नंबर के opcode लेते हैं।
रेयान

4

सिर्फ इसलिए कि कुछ सस्ता है इसका मतलब यह लागत प्रभावी नहीं है

यदि हम आपका तर्क विज्ञापन अनुपस्थिति लेते हैं, तो हम इस निष्कर्ष पर पहुंचेंगे कि सीपीयू को एनओपी निर्देश के सैकड़ों फ्लेवरों से बना होना चाहिए - क्योंकि वे लागू करने के लिए सबसे सस्ता हैं।

या इसकी तुलना वित्तीय साधनों से करें: क्या आप 0.01% रिटर्न के साथ $ 1 बॉन्ड खरीदेंगे क्योंकि आप कर सकते हैं? नहीं, आप उन डॉलर को तब तक बचाए रखेंगे जब तक आपके पास बेहतर रिटर्न के साथ $ 10 का बॉन्ड खरीदने के लिए पर्याप्त न हो। एक सीपीयू पर सिलिकॉन बजट के साथ चला जाता है: यह नंद की तरह कई सस्ते लेकिन बेकार ऑप्स को कुल्हाड़ी मारने के लिए प्रभावी है, और बचाया ट्रांजिस्टर को किसी तरह से अधिक महंगा लेकिन वास्तव में उपयोगी माना जाता है।

ज्यादा से ज्यादा ऑप्स होने की कोई रेस नहीं है। जैसा कि आरआईएससी बनाम सीआईएससी ने साबित किया था कि ट्यूरिंग शुरू से ही जानता था: कम अधिक है। वास्तव में जितना संभव हो उतना कम ऑप्स होना बेहतर है।


nopअन्य सभी लॉजिक गेट लागू नहीं कर सकते, लेकिन nandया nor, प्रभावी रूप से किसी भी अनुदेश कि सॉफ्टवेयर में एक सीपीयू में कार्यान्वित किया जाता पुन: कर सकते हैं। यदि हम RISC दृष्टिकोण लेते हैं, तो वह है ..
अमुमू

@ अम्मू मुझे लगता है कि आप मिश्रण कर रहे हैं gateऔर instruction। गेट्स का उपयोग निर्देशों को लागू करने के लिए किया जाता है, न कि दूसरे तरीके से। NOPएक निर्देश है, गेट नहीं। और हां, सभी निर्देशों को लागू करने के लिए सीपीयू में हजारों या शायद लाखों नंद द्वार भी होते हैं। बस "नंद" निर्देश नहीं।
एजेंट_

2
@Amumu यह RISC दृष्टिकोण नहीं है :) यह "सबसे व्यापक सार का उपयोग करें" दृष्टिकोण है, जो बहुत विशिष्ट अनुप्रयोगों के बाहर भी उपयोगी नहीं है। ज़रूर, nandएक द्वार है जिसका उपयोग अन्य फाटकों को लागू करने के लिए किया जा सकता है; लेकिन आपके पास पहले से ही अन्य सभी निर्देश हैं । एक nandनिर्देश का उपयोग करके उन्हें फिर से लागू करना धीमा होगा । और वे बहुत बार उपयोग किए जाते हैं ताकि सहन करने के लिए, आपके चेरी-चुने हुए विशिष्ट उदाहरण के विपरीत जहां nandकम कोड ( तेजी से कोड नहीं , बस कम) का उत्पादन होगा ; लेकिन यह अत्यंत दुर्लभ है, और लाभ केवल लागत के लायक नहीं है।
लुआं

@Amumu यदि हम आपके दृष्टिकोण का उपयोग करते हैं, तो हमारे पास स्थितीय संख्या नहीं होगी। क्या बात है जब आप केवल ((((()))))5 के बजाय सही कह सकते हैं ? पांच केवल एक विशिष्ट संख्या है, इस तरह से बहुत सीमित है - सेट कहीं अधिक सामान्य हैं: पी
लुअन

@Agent_L हाँ, मुझे पता है कि फाटक निर्देश लागू करते हैं। nandसभी फाटकों को लागू करता है, इसलिए अंतर्निहित रूप से nandअन्य सभी निर्देशों को लागू कर सकता है। फिर, यदि किसी प्रोग्रामर के पास कोई nandनिर्देश उपलब्ध है, तो वह तर्क गेट्स में सोचते समय अपने निर्देशों का आविष्कार कर सकता है। मेरा शुरू से मतलब था कि अगर यह इतना मौलिक है, तो इसे अपना निर्देश क्यों नहीं दिया गया (यानी डिकोडर लॉजिक में एक ओपोड), इसलिए एक प्रोग्रामर ऐसे निर्देश का उपयोग कर सकता है। निश्चित रूप से मुझे जवाब मिलने के बाद, अब मुझे पता है कि यह सॉफ्टवेयर के उपयोग पर निर्भर करता है।
अमुमु

3

एक हार्डवेयर स्तर पर, या तो नंद है या न ही प्राथमिक तर्क ऑपरेशन है। तकनीक पर निर्भर करता है (या आप जिसे मनमाने ढंग से 1 कहते हैं और जिसे आप 0 कहते हैं) पर निर्भर करता है, या तो नंद या बहुत ही सरल, प्रारंभिक तरीके से लागू किया जा सकता है।

यदि हम "और न ही" मामले को अनदेखा करते हैं, तो अन्य सभी तर्क नंद से निर्मित होते हैं। लेकिन इसलिए नहीं कि कुछ कंप्यूटर विज्ञान प्रमाण है कि सभी तर्क संचालन का निर्माण किया जा सकता है और - इसका कारण यह है कि बस कोई प्राथमिक विधि नहीं है xor बनाने के लिए, या आदि और जो बेहतर है तो नंद से इसका निर्माण करना।

कंप्यूटर निर्देशों के लिए, स्थिति अलग है। एक नंद निर्देश लागू किया जा सकता है, और यह उदाहरण के लिए, Xor को लागू करने की तुलना में थोड़ा सस्ता होगा। लेकिन केवल एक छोटा सा, क्योंकि तर्क जो परिणाम की गणना करता है वह उस तर्क की तुलना में छोटा होता है जो निर्देश को डिकोड करता है, ऑपरेंड को इधर-उधर करता है, यह सुनिश्चित करता है कि एक ऑपरेशन केवल गणना है, और परिणाम को चुनता है और इसे सही जगह पर पहुंचाता है। प्रत्येक निर्देश को निष्पादित करने के लिए एक चक्र होता है, साथ ही तर्क के संदर्भ में दस गुना अधिक जटिल होता है। नंद बनाम xor की बचत नगण्य होगी।

फिर क्या मायने रखता है कि ऑपरेशन के लिए कितने निर्देशों की आवश्यकता होती है जो वास्तव में विशिष्ट कोड द्वारा किए जाते हैं । नंद आम तौर पर अनुरोध किए गए कार्यों की सूची में शीर्ष पर कहीं नहीं है। यह बहुत अधिक सामान्य है कि और, या, अनुरोध नहीं किया जाता है। प्रोसेसर और निर्देश सेट डिजाइनर मौजूदा कोड के बहुत से परीक्षण करेंगे और निर्धारित करेंगे कि विभिन्न निर्देश उस कोड को कैसे प्रभावित करेंगे। वे सबसे अधिक संभावना है कि एक नंद अनुदेश जोड़ने के लिए विशिष्ट कोड को चलाने के लिए निष्पादित करने वाले प्रोसेसर निर्देशों की संख्या में बहुत कम कमी आएगी, और नंद के साथ कुछ मौजूदा अनुदेशों को प्रतिस्थापित करने से निष्पादित अनुदेश की संख्या बढ़ जाएगी।


2

सिर्फ इसलिए कि एनएएनडी (या एनओआर) कॉम्बिनेशन लॉजिक के सभी फाटकों को लागू कर सकता है, उसी तरह कुशल बिटवाइज़ ऑपरेटर में अनुवाद नहीं करता है। AND को लागू करने के लिए केवल NAND संचालन का उपयोग करते हुए, जहाँ c = a और b, आपको c = एक NAND b, फिर b = -1, फिर c = c NAND b (NOT के लिए) होना चाहिए। मूल तर्क बिटवाइज़ ऑपरेशन AND, OR, EOR, NOT, NAND और NEOR हैं। यह कवर करने के लिए बहुत कुछ नहीं है, और पहले चार आम तौर पर वैसे भी बनाए जाते हैं। कॉम्बिनेशन लॉजिक में, बेसिक लॉजिक सर्किट केवल उपलब्ध गेट्स की संख्या द्वारा सीमित होते हैं, जो पूरी तरह से एक अलग बॉल गेम है। एक प्रोग्राम गेट एरे में संभावित अंतर्संबंधों की संख्या, जो लगता है कि आप वास्तव में क्या हैं, वास्तव में एक बहुत बड़ी संख्या होगी। कुछ प्रोसेसर वास्तव में गेट एरे में निर्मित होते हैं।


0

आप एक तर्क गेट को सिर्फ इसलिए लागू नहीं करते हैं क्योंकि इसमें कार्यात्मकता पूर्णता है, खासकर यदि अन्य लॉजिक गेट मूल रूप से उपलब्ध हैं। आप कार्यान्वित करते हैं जो संकलक द्वारा सबसे अधिक उपयोग किया जाता है।

NAND, NOR और XNOR की बहुत कम जरूरत होती है। शास्त्रीय बिटवाइज़ ऑपरेटरों और ओआर और एक्सओआर के अलावा, केवल ANDN ( ~a & b) - जो नंद नहीं है ( ~(a & b)) - एक व्यावहारिक उपयोगिता होगी। यदि कोई हो, तो एक CPU को लागू करना चाहिए (और वास्तव में कुछ CPU ANDN लागू करते हैं)।

ANDN की व्यावहारिक उपयोगिता की व्याख्या करने के लिए, कल्पना करें कि आपके पास एक बिटमास्क है जो कई बिट्स का उपयोग करता है, लेकिन आप केवल उनमें से कुछ में रुचि रखते हैं, जो निम्नलिखित हैं:

enum my_flags {
    IT_IS_FRIDAY = 1,
    ...
    IT_IS_WARM = 8,
    ...
    THE_SUN_SHINES = 64,
    ...
};

आम तौर पर आप बिटमस्क में अपनी रुचि के बिट्स के बारे में जांचना चाहते हैं कि क्या

  1. वे सभी सेट हैं
  2. कम से कम एक सेट है
  3. कम से कम एक सेट नहीं है
  4. कोई भी सेट नहीं है

चलो अपने हित के बिट्स को एक साथ इकट्ठा करके शुरू करते हैं:

#define BITS_OF_INTEREST (IT_IS_FRIDAY | IT_IS_WARM | THE_SUN_SHINES)

1. ब्याज की सभी बिट्स सेट की गई हैं: बिटवाइंड ANDN + तार्किक नहीं

मान लीजिए कि आप जानना चाहते हैं कि आपके बिट ऑफ इंटरेस्ट सेट हैं या नहीं। आप इसे इस तरह देख सकते हैं (my_bitmask & IT_IS_FRIDAY) && (my_bitmask & IT_IS_WARM) && (my_bitmask & THE_SUN_SHINES)। हालांकि आम तौर पर आप उस में पतन होगा

unsigned int life_is_beautiful = !(~my_bitmask & BITS_OF_INTEREST);

2. कम से कम एक बिट ब्याज निर्धारित है: बिटवाइज़ और

अब मान लीजिए कि आप जानना चाहते हैं कि क्या कम से कम एक बिट ब्याज निर्धारित है। आप इसे देख सकते हैं (my_bitmask & IT_IS_FRIDAY) || (my_bitmask & IT_IS_WARM) || (my_bitmask & THE_SUN_SHINES)। हालांकि आम तौर पर आप उस में पतन होगा

unsigned int life_is_not_bad = my_bitmask & BITS_OF_INTEREST;

3. कम से कम एक बिट ब्याज निर्धारित नहीं है: बिटवाइंड ANDN

अब मान लीजिए कि आप जानना चाहते हैं कि क्या कम से कम एक बिट ब्याज निर्धारित नहीं है। आप इसे देख सकते हैं !(my_bitmask & IT_IS_FRIDAY) || !(my_bitmask & IT_IS_WARM) || !(my_bitmask & THE_SUN_SHINES)। हालांकि आम तौर पर आप उस में पतन होगा

unsigned int life_is_imperfect = ~my_bitmask & BITS_OF_INTEREST;

4. किसी भी तरह का ब्याज निर्धारित नहीं है: बिटवाइज़ और + तार्किक नहीं

अब मान लीजिए कि आप जानना चाहते हैं कि क्या सभी बिट्स सेट नहीं हैं। आप इसे देख सकते हैं !(my_bitmask & IT_IS_FRIDAY) && !(my_bitmask & IT_IS_WARM) && !(my_bitmask & THE_SUN_SHINES)। हालांकि आम तौर पर आप उस में पतन होगा

unsigned int life_is_horrible = !(my_bitmask & BITS_OF_INTEREST);

ये एक बिटकॉम्ब पर किए जाने वाले सामान्य ऑपरेशन हैं, साथ ही क्लासिकल बिटवाइज़ OR और XOR। मुझे लगता है कि हालांकि, एक भाषा (जो सीपीयू नहीं है ) में बिटवाइंड नंद, एनओआर और एक्सएनओआर ऑपरेटरों (जिनके प्रतीक होंगे ~&, ~|और ~^) को शायद ही कभी इस्तेमाल किया जाना चाहिए । मैं ANDN ऑपरेटर को किसी भाषा में शामिल नहीं करूंगा, क्योंकि यह कम्यूटेटिव नहीं है ( a ANDN bजैसा नहीं है b ANDN a) - ~a & bइसके बजाय लिखने के लिए बेहतर है a ANDN b, पूर्व में ऑपरेशन की विषमता अधिक स्पष्ट रूप से दिखाई देती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.