ডাফের ডিভাইস কীভাবে কাজ করে?


147

আমি ড্যাফের ডিভাইসে উইকিপিডিয়ায় নিবন্ধটি পড়েছি এবং এটি পাই না। আমি সত্যিই আগ্রহী, তবে আমি সেখানে ব্যাখ্যাটি বেশ কয়েকবার পড়েছি এবং ডাফের ডিভাইস কীভাবে কাজ করে তা এখনও পাই না।

এর আরও বিশদ ব্যাখ্যা কী হবে?

উত্তর:


240

অন্য কোথাও কিছু ভাল ব্যাখ্যা আছে, তবে আমাকে এটি দিয়ে চেষ্টা করুন। (এটি হোয়াইটবোর্ডে অনেক সহজ!) উইকিপিডিয়া উদাহরণটি এখানে কিছু স্বীকৃতি সহ।

ধরা যাক আপনি 20 বাইট অনুলিপি করছেন। প্রথম পাসের জন্য প্রোগ্রামটির প্রবাহ নিয়ন্ত্রণ:

int count;                        // Set to 20
{
    int n = (count + 7) / 8;      // n is now 3.  (The "while" is going
                                  //              to be run three times.)

    switch (count % 8) {          // The remainder is 4 (20 modulo 8) so
                                  // jump to the case 4

    case 0:                       // [skipped]
             do {                 // [skipped]
                 *to = *from++;   // [skipped]
    case 7:      *to = *from++;   // [skipped]
    case 6:      *to = *from++;   // [skipped]
    case 5:      *to = *from++;   // [skipped]
    case 4:      *to = *from++;   // Start here.  Copy 1 byte  (total 1)
    case 3:      *to = *from++;   // Copy 1 byte (total 2)
    case 2:      *to = *from++;   // Copy 1 byte (total 3)
    case 1:      *to = *from++;   // Copy 1 byte (total 4)
           } while (--n > 0);     // N = 3 Reduce N by 1, then jump up
                                  //       to the "do" if it's still
    }                             //        greater than 0 (and it is)
}

এখন, দ্বিতীয় পাসটি শুরু করুন, আমরা কেবল নির্দেশিত কোডটি চালাই:

int count;                        //
{
    int n = (count + 7) / 8;      //
                                  //

    switch (count % 8) {          //
                                  //

    case 0:                       //
             do {                 // The while jumps to here.
                 *to = *from++;   // Copy 1 byte (total 5)
    case 7:      *to = *from++;   // Copy 1 byte (total 6)
    case 6:      *to = *from++;   // Copy 1 byte (total 7)
    case 5:      *to = *from++;   // Copy 1 byte (total 8)
    case 4:      *to = *from++;   // Copy 1 byte (total 9)
    case 3:      *to = *from++;   // Copy 1 byte (total 10)
    case 2:      *to = *from++;   // Copy 1 byte (total 11)
    case 1:      *to = *from++;   // Copy 1 byte (total 12)
           } while (--n > 0);     // N = 2 Reduce N by 1, then jump up
                                  //       to the "do" if it's still
    }                             //       greater than 0 (and it is)
}

এখন, তৃতীয় পাসটি শুরু করুন:

int count;                        //
{
    int n = (count + 7) / 8;      //
                                  //

    switch (count % 8) {          //
                                  //

    case 0:                       //
             do {                 // The while jumps to here.
                 *to = *from++;   // Copy 1 byte (total 13)
    case 7:      *to = *from++;   // Copy 1 byte (total 14)
    case 6:      *to = *from++;   // Copy 1 byte (total 15)
    case 5:      *to = *from++;   // Copy 1 byte (total 16)
    case 4:      *to = *from++;   // Copy 1 byte (total 17)
    case 3:      *to = *from++;   // Copy 1 byte (total 18)
    case 2:      *to = *from++;   // Copy 1 byte (total 19)
    case 1:      *to = *from++;   // Copy 1 byte (total 20)
           } while (--n > 0);     // N = 1  Reduce N by 1, then jump up
                                  //       to the "do" if it's still
    }                             //       greater than 0 (and it's not, so bail)
}                                 // continue here...

20 বাইট এখন অনুলিপি করা হয়।

দ্রষ্টব্য: মূল ডাফের ডিভাইস (উপরে দেখানো) toঠিকানায় আই / ও ডিভাইসে অনুলিপি করা হয়েছে । সুতরাং, পয়েন্টারটি বাড়ানোর প্রয়োজন ছিল না *to। দুটি মেমরি বাফারগুলির মধ্যে অনুলিপি করার সময় আপনাকে ব্যবহার করতে হবে *to++


1
কেস 0: ক্লজটি কীভাবে বাদ দেওয়া যায় এবং লুপের সময় থাকা অন্যান্য ধারাগুলির জন্য পরীক্ষা করা চালিয়ে যাওয়া যায় যে এড়িয়ে যাওয়া ধারাটির যুক্তি? লুপটি স্কিপ করার সময় যদি কেবলমাত্র ক্লজটি ডু-এর বাইরে থাকে তবে স্যুইচ কেন সেখানে শেষ হয় না?
অরেলিয়াস

14
ধনুর্বন্ধনী তাকান না এত শক্ত। doএত কিছুর দিকে তাকাবেন না । পরিবর্তে, switchএবং whileপুরানো ফ্যাশন হিসাবে গণিত GOTOস্ট্যাটাস বা jmpঅফসেট সহ এসেম্বলারের বিবৃতি হিসাবে দেখুন। switchকিছু গণিত করে এবং তারপর jmpসঠিক জায়গায় s। whileএকটি বুলিয়ান চেক করে এবং তারপর অন্ধভাবে jmpসম্পর্কে যেখানে ডান দিকে গুলি doছিল।
ক্লিনটন পিয়ার্স

এটি যদি এত ভাল হয় তবে সবাই কেন এটি ব্যবহার করে না? কোন ত্রুটি আছে?
আলফাগোকু

@ আলফাগোকু পাঠযোগ্যতা।
এলএফ

108

ডাঃ Dobb এর জার্নালে ব্যাখ্যা শ্রেষ্ঠ যে আমি বিষয়ে পাওয়া যায়।

এটি আমার আহা মুহুর্ত হচ্ছে:

for (i = 0; i < len; ++i) {
    HAL_IO_PORT = *pSource++;
}

হয়ে:

int n = len / 8;
for (i = 0; i < n; ++i) {
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
    HAL_IO_PORT = *pSource++;
}

n = len % 8;
for (i = 0; i < n; ++i) {
    HAL_IO_PORT = *pSource++;
}

হয়ে:

int n = (len + 8 - 1) / 8;
switch (len % 8) {
    case 0: do { HAL_IO_PORT = *pSource++;
    case 7: HAL_IO_PORT = *pSource++;
    case 6: HAL_IO_PORT = *pSource++;
    case 5: HAL_IO_PORT = *pSource++;
    case 4: HAL_IO_PORT = *pSource++;
    case 3: HAL_IO_PORT = *pSource++;
    case 2: HAL_IO_PORT = *pSource++;
    case 1: HAL_IO_PORT = *pSource++;
               } while (--n > 0);
}

ভাল পোস্ট (প্লাস আমার আপনার উত্সাহিত করার জন্য একটি ভাল উত্তর খুঁজে পেতে হবে;) 2 ডাউন, 13 টি যেতে হবে: stackoverflow.com/questions/359727#486543 )। সুন্দর উত্তর ব্যাজ উপভোগ করুন।
ভোনসি

13
এখানে গুরুত্বপূর্ণ ঘটনা, এবং যা ডফের ডিভাইসটি আমার কাছে দীর্ঘ সময়ের জন্য অবিচ্ছিন্ন করে তুলেছিল তা হ'ল প্রথমবারের মতো যখন এটি পৌঁছায় তখন সি'র এক ছিটকিনি দিয়ে তা পিছনে আসে এবং সমস্ত বিবৃতি কার্যকর করে। সুতরাং len%84 হলেও , এটি কেস 4, কেস 2, কেস 2, এবং কেস 1 কার্যকর করবে এবং তারপরে পিছনে ঝাঁপিয়ে পড়বে এবং পরবর্তী লুপ থেকে সমস্ত কেস কার্যকর করবে। এটি সেই অংশ যা ব্যাখ্যা করা দরকার, লুপটি এবং সুইচ বিবৃতিটি "ইন্টারঅ্যাক্ট" করে।
শ্রীভাত্সআর

2
ডাঃ ডবস নিবন্ধটি ভাল তবে লিঙ্কটি বাদ দিয়ে উত্তরটি কিছু যুক্ত করে না। নীচে রব কেনেডি এর উত্তর দেখুন যা প্রথমে হস্তান্তরিত আকারের বাকি অংশ সম্পর্কে প্রথমে একটি গুরুত্বপূর্ণ পয়েন্ট সরবরাহ করে তারপরে শূন্য বা 8 টি বাইটের আরও ট্রান্সফার ব্লক অনুসরণ করা হয়। আমার মতে এই কোডটি বোঝার মূল চাবিকাঠি।
রিচার্ড চেম্বারস 23

3
আমি কি কিছু মিস করছি, বা দ্বিতীয় কোডে স্নিপেট len % 8বাইটগুলি অনুলিপি করা হবে না?
নবাগত

আমি আটকে গিয়েছিলাম, ভুলে যাচ্ছি যে আপনি যদি কোনও মামলার বিবৃতি তালিকা শেষে ব্রেক স্টেটমেন্ট না লিখেন, সি (বা অন্য কোনও ভাষা) বিবৃতি কার্যকর করতে থাকবে। সুতরাং আপনি যদি ভাবছেন যে ডাফের ডিভাইসটি
এগুলি

75

ডাফের ডিভাইসে দুটি মূল বিষয় রয়েছে। প্রথমত, যা আমি সন্দেহ করি তা বোঝা সহজতর অংশ, লুপটি অনিয়ন্ত্রিত। লুপটি শেষ হয়েছে কিনা তা পরীক্ষা করে এবং লুপের শীর্ষে ফিরে এসে জড়িত কিছু ওভারহেডকে এড়িয়ে আরও গতির জন্য এটি বৃহত্তর কোড আকারের ব্যবসা করে। যখন জাম্পিংয়ের পরিবর্তে সরলরেখার কোডটি চালায় তখন সিপিইউ দ্রুত চালাতে পারে।

দ্বিতীয় দিকটি হ'ল সুইচ স্টেটমেন্ট। এটি কোডটিকে প্রথমবারের মধ্য দিয়ে লুপের মাঝখানে লাফ দেওয়ার অনুমতি দেয় । বেশিরভাগ লোকের কাছে অবাক করা বিষয়টি হ'ল এই জাতীয় জিনিস অনুমোদিত। ঠিক আছে, এটি অনুমোদিত। এক্সিকিউশন গণনা করা কেস লেবেল থেকে শুরু হয় এবং তারপরে এটি প্রতিটি ক্রমাগত কার্যনির্বাহী বিবৃতিতে পড়ে , যেমন অন্য কোনও সুইচ স্টেটমেন্টের মতো। শেষ কেস লেবেলের পরে, এক্সিকিউশনটি লুপের নীচে পৌঁছে যায়, যে সময়ে এটি শীর্ষে ফিরে আসে। লুপ শীর্ষে অবস্থিত ভিতরে তাই সুইচ আর না পুনরায় মূল্যায়ন করা হয়, সুইচ বিবৃতি।

মূল লুপটি আটবার অবিরাম হয়, সুতরাং পুনরাবৃত্তির সংখ্যা আট দ্বারা বিভক্ত হয়। যদি অনুলিপি করা বাইটের সংখ্যা আটটির একাধিক না হয়, তবে কিছু বাইট বাকি আছে। বেশিরভাগ অ্যালগরিদম যা বাইটের ব্লকগুলি একবারে অনুলিপি করে তা বাকি বাক্যগুলি হ্যান্ডেল করবে, তবে ডাফের ডিভাইস শুরুতেই এগুলি পরিচালনা করে। count % 8বাকীটি কী হবে তা নির্ধারণ করার জন্য ফাংশনটি স্যুইচ স্টেটমেন্টের জন্য গণনা করে , সেই অনেকগুলি বাইটের জন্য কেস লেবেলে ঝাঁপ দেয় এবং সেগুলি অনুলিপি করে। তারপরে লুপ আটটি বাইটের গ্রুপগুলি অনুলিপি করে চলেছে।


5
এই ব্যাখ্যা আরও বোধগম্য। আমার বোঝার জন্য কীটি বাকিটি প্রথমে অনুলিপি করা হয়েছে তারপরে বাকি 8 টি বাইটের ব্লক করা হয়েছে যা অস্বাভাবিক কারণ যেহেতু বেশিরভাগ সময় উল্লিখিত হয়েছে, আপনি 8 বাইটের ব্লকে অনুলিপি করে বাকীটি অনুলিপি করবেন। বাকিটি আগে করা এই অ্যালগরিদম বোঝার মূল চাবিকাঠি।
রিচার্ড চেম্বারস

পাগল প্লেসমেন্ট / সুইচ নেস্টিং / যখন লুপের উল্লেখের জন্য +1 জাভা মত ভাষা থেকে আসা কল্পনা করা অসম্ভব ...
পরোব

13

ডফস ডিভাইসের বিন্দুটি হ'ল একটি শক্ত মেমকি প্রয়োগের ক্ষেত্রে তুলনার সংখ্যা হ্রাস করা।

মনে করুন আপনি একটি থেকে বি থেকে 'গণনা' বাইটগুলি অনুলিপি করতে চান, সরাসরি এগিয়ে যাওয়ার পদ্ধতিটি নিম্নলিখিতটি করা:

  do {                      
      *a = *b++;            
  } while (--count > 0);

এটি 0 এর ওপরে কিনা তা দেখতে আপনাকে কতবার গণনার তুলনা করতে হবে? 'গণনা' বার।

এখন, ডাফ ডিভাইসটি একটি স্যুইচ কেসের একটি অদ্ভুত অনিচ্ছাকৃত পার্শ্ব প্রতিক্রিয়া ব্যবহার করে যা আপনাকে 8 / গণনা করার জন্য প্রয়োজনীয় তুলনা সংখ্যা হ্রাস করতে দেয়।

এখন ধরুন আপনি ডাফস ডিভাইসটি ব্যবহার করে 20 বাইট অনুলিপি করতে চান, আপনার কতটি তুলনা প্রয়োজন? শুধুমাত্র 3, যেহেতু আপনি সর্বশেষ প্রথমটি ব্যতীত এক সময় আটটি বাইট অনুলিপি করেন যেখানে আপনি কেবল 4 টি অনুলিপি করেন।

আপডেট করা: আপনাকে 8 টি তুলনা / কেস-ইন-স্যুইচ বিবৃতি করতে হবে না, তবে এটি ফাংশনের আকার এবং গতির মধ্যে একটি বাণিজ্য-যুক্তিসঙ্গত reasonable


3
নোট করুন যে ডাফের ডিভাইসটি স্যুইচ বিবৃতিতে 8 টি সদৃশ সীমাবদ্ধ নয়।
স্ট্র্যাজার

কেন আপনি কেবল - হিসাব, ​​গণনা = গণনা -8 এর পরিবর্তে ব্যবহার করতে পারবেন না? এবং বাকীটি মোকাবেলায় দ্বিতীয় লুপটি ব্যবহার করবেন?
হাফেজ

1
হাফেজ, আপনি বাকীটি মোকাবেলায় দ্বিতীয় লুপটি ব্যবহার করতে পারেন। কিন্তু এখন আপনি গতি বাড়িয়ে না দিয়ে একই জিনিসটি সম্পাদনের জন্য দ্বিগুণ কোড করেছেন।
রব কেনেডি

জোহান, আপনি এটি পিছনে আছে। বাকি 4 বাইট লুপের প্রথম পুনরাবৃত্তিতে অনুলিপি করা হয় , শেষ নয়।
রব কেনেডি

8

আমি যখন প্রথমবার এটি পড়ি তখন আমি এটিকে স্বয়ংক্রিয়ভাবে তৈরি করেছি

void dsend(char* to, char* from, count) {
    int n = (count + 7) / 8;
    switch (count % 8) {
        case 0: do {
                *to = *from++;
                case 7: *to = *from++;
                case 6: *to = *from++;
                case 5: *to = *from++;
                case 4: *to = *from++;
                case 3: *to = *from++;
                case 2: *to = *from++;
                case 1: *to = *from++;
            } while (--n > 0);
    }
}

এবং আমার কি ধারণা ছিল না যে কি ঘটছে।

এই প্রশ্নটি যখন জিজ্ঞাসা করা হয়েছিল তখন নাও হতে পারে তবে এখন উইকিপিডিয়ায় খুব ভাল ব্যাখ্যা রয়েছে

ডিটিতে দুটি বৈশিষ্ট্যের কারণে ডিভাইসটি বৈধ, বৈধ সি:

  • ভাষার সংজ্ঞাটিতে স্যুইচ স্টেটমেন্টের স্বাচ্ছন্দ্য বিবরণ। ডিভাইসের উদ্ভাবনের সময় এটি সি প্রোগ্রামিং ল্যাঙ্গুয়েজের প্রথম সংস্করণ ছিল যার জন্য কেবল প্রয়োজন যে স্যুইচটির নিয়ন্ত্রিত বিবৃতিটি একটি সিনট্যাক্টিক্যালি বৈধ (যৌগিক) বিবৃতি হওয়া উচিত যার মধ্যে কেস লেবেলগুলি কোনও উপ-বিবৃতি উপস্থাপনের জন্য উপস্থিত হতে পারে। একটি ব্রেক স্টেটমেন্টের অভাবে, নিয়ন্ত্রণের প্রবাহ একটি কেস লেবেল দ্বারা নিয়ন্ত্রিত একটি স্টেটমেন্ট থেকে পরবর্তী দ্বারা নিয়ন্ত্রিত একটি বিবৃতি থেকে নিয়ন্ত্রণের সাথে মিলিত হবে, এর অর্থ এই কোডটি গণনা অনুলিপিগুলির উত্তরসূরি নির্দিষ্ট করে মেমোরি-ম্যাপযুক্ত আউটপুট পোর্টে ক্রমিক উত্স ঠিকানাগুলি।
  • সিটিতে লুপের মাঝখানে আইনীভাবে লাফ দেওয়ার ক্ষমতা

6

1: ডফস ডিভাইসটি লুপ আনআরোলিংয়ের একটি বিশেষ প্রতিচ্ছবি। লুপ আনرولিং কী?
যদি আপনার কোনও লুপে N বার সঞ্চালনের অপারেশন থাকে তবে আপনি লুপ N / n বার প্রয়োগ করে এবং তারপরে লুপ ইনলাইনিং (আন্রোলিং) এ লুপ কোড এন বারের সাথে উদাহরণস্বরূপ প্রতিস্থাপন করে: প্রোগ্রামের আকারটি গতির জন্য ট্রেড করতে পারেন:

for (int i=0; i<N; i++) {
    // [The loop code...] 
}

সঙ্গে

for (int i=0; i<N/n; i++) {
    // [The loop code...]
    // [The loop code...]
    // [The loop code...]
    ...
    // [The loop code...] // n times!
}

N% n == 0 - ডফের দরকার নেই যদি এটি দুর্দান্ত কাজ করে! যদি এটি সত্য না হয় তবে আপনাকে বাকীটি পরিচালনা করতে হবে - যা একটি ব্যথা।

2: ড্যাফস ডিভাইসটি কীভাবে এই মানক লুপটি আন্রোলিং থেকে আলাদা হয়?
ডফস ডিভাইসটি যখন বাকি% লুপ চক্রগুলি মোকাবেলা করার জন্য কেবল একটি চতুর উপায়, যখন N% n! = 0. সম্পূর্ণভাবে / যখন মান / লুপ আন্রোলিং অনুসারে N / n সংখ্যাটি কার্যকর করে (কারণ কেস 0 প্রযোজ্য)। লুপের মাধ্যমে শেষ দৌড়ে ('N / n + 1'th বার) কেসটি শুরু হয় এবং আমরা N% n কেটে চলে যাই এবং লুপ কোডটি' বাকী 'সংখ্যাটি চালাই।


এই প্রশ্নের পরে আমি ডাফস ডিভাইসে আগ্রহ পেয়েছি: stackoverflow.com/questions/17192246/switch-case-Wider-scoping তাই আইডির ডফকে স্পষ্ট করা যায় - নিশ্চিত নয় যে এটি বিদ্যমান উত্তরের উপর কোনও উন্নতি কিনা ...
রিকিবব

3

আপনি যা চাইছেন তা আমি 100% নিশ্চিত না হলেও, এখানে ...

ডফের ডিভাইসটির ঠিকানাটি যে লুপটি আনমন্ডিংয়ের মধ্যে রয়েছে তা হ'ল (আপনি যে পোস্ট করেছেন উইকি লিঙ্কটিতে আপনি অবশ্যই সন্দেহ প্রকাশ করেছেন)। এটির সাথে মূলত যা সমান হয় তা হ'ল মেমরির পদক্ষেপের চেয়ে রান-টাইম দক্ষতার একটি অপ্টিমাইজেশন। ডাফের ডিভাইসটি কেবল কোনও পুরানো সমস্যার চেয়ে সিরিয়াল অনুলিপি নিয়ে কাজ করে, তবে একটি লুপের তুলনায় যে পরিমাণ তুলনা করা প্রয়োজন তার সংখ্যা হ্রাস করে কীভাবে অনুকূলিতকরণ করা যায় তার একটি সর্বোত্তম উদাহরণ।

বিকল্প উদাহরণ হিসাবে, এটি বুঝতে সহজ করে তুলতে পারে, কল্পনা করুন যে আপনি লুপ করতে চান এমন আইটেমের একটি অ্যারে রেখেছেন এবং প্রতিবার এগুলিতে 1 যোগ করুন ... সাধারণভাবে, আপনি লুপের জন্য এবং প্রায় 100 বার লুপ ব্যবহার করতে পারেন । এটি মোটামুটি যৌক্তিক বলে মনে হয় এবং এটি হ'ল ... তবে লুপটি আনওয়াইন্ড করে একটি অপ্টিমাইজেশন তৈরি করা যেতে পারে (সম্ভবত খুব বেশি দূরে নয় ... অথবা আপনি কেবল লুপটি ব্যবহার করতে পারবেন না)।

লুপের জন্য একটি নিয়মিত:

for(int i = 0; i < 100; i++)
{
    myArray[i] += 1;
}

হয়ে

for(int i = 0; i < 100; i+10)
{
    myArray[i] += 1;
    myArray[i+1] += 1;
    myArray[i+2] += 1;
    myArray[i+3] += 1;
    myArray[i+4] += 1;
    myArray[i+5] += 1;
    myArray[i+6] += 1;
    myArray[i+7] += 1;
    myArray[i+8] += 1;
    myArray[i+9] += 1;
}

ডাফের ডিভাইস যা করে তা হ'ল এই ধারণাটি বাস্তবায়িত করে সি তে, তবে (যেমন আপনি উইকিতে দেখেছেন) সিরিয়াল অনুলিপি সহ। আপনি উপরের অবাঞ্ছিত উদাহরণ সহ যা দেখছেন তা মূলের 100 এর সাথে তুলনা করে 10 - এটি একটি গৌণ, তবে সম্ভবত তাত্পর্যপূর্ণ, অপ্টিমাইজেশনের পরিমাণ।


8
আপনি মূল অংশটি মিস করছেন। এটি কেবল লুপ আনওয়ানডিং সম্পর্কে নয়। স্যুইচ স্টেটমেন্টটি লুপের মাঝখানে লাফ দেয়। এটিই ডিভাইসটিকে এত বিভ্রান্ত দেখাচ্ছে। আপনার লুপটি সর্বদা 10 কপির একাধিক সঞ্চালন করে তবে ডাফ এর যে কোনও সংখ্যা সম্পাদন করে।
রব কেনেডি

2
এটি সত্য - তবে আমি ওপিটির জন্য বর্ণনাটি সহজ করার চেষ্টা করছিলাম। সম্ভবত আমি যথেষ্ট যে পরিষ্কার ছিল না! :)
জেমস বি

2

এখানে একটি অ-বিশদ বিবরণ যা ডফের ডিভাইসের কর্কস বলে আমি মনে করি:

বিষয়টি হ'ল সি মূলত অ্যাসেম্বলি ভাষার জন্য একটি সুন্দর মুখোমুখি (পিডিপি -7 অ্যাসেমব্লিকে নির্দিষ্ট করার জন্য; আপনি যদি অধ্যয়ন করেন তবে দেখতে পাবেন যে মিলগুলি কতটা আকর্ষণীয়)। এবং, সমাবেশের ভাষায়, আপনার কাছে আসলে লুপ নেই - আপনার কাছে লেবেল এবং শর্তসাপেক্ষে - শাখার নির্দেশাবলী রয়েছে। সুতরাং লুপটি কোথাও একটি লেবেল এবং একটি শাখা সহ নির্দেশের সামগ্রিক ক্রমের কেবলমাত্র একটি অংশ:

        instruction
label1: instruction
        instruction
        instruction
        instruction
        jump to label1  some condition

এবং একটি স্যুইচ নির্দেশ শাখা করা / কিছুটা এগিয়ে লাফিয়ে:

        evaluate expression into register r
        compare r with first case value
        branch to first case label if equal
        compare r with second case value
        branch to second case label if equal
        etc....
first_case_label: 
        instruction
        instruction
second_case_label: 
        instruction
        instruction
        etc...

সমাবেশে এটি কীভাবে এই দুটি কন্ট্রোল স্ট্রাকচারকে একত্রিত করা যায় তা সহজেই অনুমেয় এবং আপনি যখন সেভাবে মনে করেন, সি-তে তাদের সংমিশ্রণটি এত অদ্ভুত বলে মনে হয় না।


1

এটি একটি উত্তর যা আমি ডাফের ডিভাইস সম্পর্কে অন্য একটি পোস্টে পোস্ট করেছিলাম যা সদৃশ হিসাবে প্রশ্নটি বন্ধ হওয়ার আগে কিছু উপকার পেয়েছিল। আমি মনে করি এটি কেন আপনার এই নির্মাণটি এড়ানো উচিত সে সম্পর্কে এখানে কিছুটা মূল্যবান প্রসঙ্গ সরবরাহ করে।

"এটি ডাফের ডিভাইস It's

যেহেতু এখানে বেশিরভাগ উত্তরগুলি সাধারণভাবে ইতিবাচক বলে মনে হয় আমি ডাউনসাইডগুলি হাইলাইট করতে যাচ্ছি।

এই কোডের সাহায্যে একটি সংকলক লুপের বডিটিতে কোনও অপ্টিমাইজেশন প্রয়োগ করতে লড়াই করতে চলেছে। আপনি যদি স্রেফ লুপ হিসাবে কোডটি লিখে থাকেন তবে আধুনিক সংকলকটি আপনার জন্য এই তালিকাভুক্তি নিয়ন্ত্রণ করতে সক্ষম হবে। এইভাবে আপনি পঠনযোগ্যতা এবং কার্য সম্পাদন বজায় রাখবেন এবং লুপ বডিতে অন্যান্য অপ্টিমাইজেশান প্রয়োগ হওয়ার কিছুটা আশা রয়েছে।

অন্যরা দ্বারা উল্লিখিত উইকিপিডিয়া নিবন্ধটি এমনকি আরও জানায় যে যখন এই 'প্যাটার্ন'টি Xfree86 উত্স কোডের কার্যকারিতা থেকে সরিয়ে নেওয়া হয়েছিল তখন বাস্তবে উন্নতি হয়েছিল।

এই ফলাফলটি আপনার যে কোনও কোডের প্রয়োজন হতে পারে বলে মনে হয় অন্ধভাবে হাত দেওয়ার জন্য of এটি কম্পাইলারটিকে সঠিকভাবে কাজ করতে বাধা দেয়, আপনার কোডটি কম পঠনযোগ্য এবং বাগের প্রবণতায় পরিণত করে এবং সাধারণত এটি ধীর করে দেয়। আপনি যদি প্রথমে জিনিসগুলি সঠিকভাবে করছিলেন, অর্থাত্ সরল কোড লেখা, তারপরে বাধাগ্রস্থের জন্য প্রোফাইলিং, তারপর অনুকূলকরণ, আপনি কখনও এই জাতীয় কিছু ব্যবহার করার কথা ভাবেননি think যাইহোক আধুনিক সিপিইউ এবং সংকলক সহ নয়।

এটি বুঝতে পেরে ভাল, তবে আপনি যদি সত্যিই এটি ব্যবহার করেন তবে আমি অবাক হব। "


0

সবেমাত্র পরীক্ষা-নিরীক্ষা করে, ইন্টারলিভিং সুইচ এবং লুপ ছাড়াই আরও একটি রূপ পেয়েছে:

int n = (count + 1) / 8;
switch (count % 8)
{
    LOOP:
case 0:
    if(n-- == 0)
        break;
    putchar('.');
case 7:
    putchar('.');
case 6:
    putchar('.');
case 5:
    putchar('.');
case 4:
    putchar('.');
case 3:
    putchar('.');
case 2:
    putchar('.');
case 1:
    putchar('.');
default:
    goto LOOP;
}

তোমার সমাপ্তির অবস্থা কোথায়?
ব্যবহারকারী 2338150
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.