একটি এসটিএম 32 এমসিইউ থেকে দ্রুত পারফরম্যান্স পাচ্ছেন


11

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

  1. এইচএসআই ঘড়ি (8 মেগাহার্টজ) চালু আছে;
  2. পিএলএল এইচএসআই / 2 * 16 = 64 মেগাহার্টজ অর্জনের জন্য 16 এর প্রেস্কেলারের সাথে শুরু করা হয়েছিল;
  3. পিএলএলকে এসওয়াইএসসিএলকে মনোনীত করা হয়েছে;
  4. এসওয়াইএসসিএলকে এমসিও পিন (PA8) এ পর্যবেক্ষণ করা হয়, এবং একটি পিনের (PE10) অনন্ত লুপে নিয়মিত টগল করা হয়।

এই প্রোগ্রামের উত্স কোডটি নীচে উপস্থাপন করা হয়েছে:

#include "stm32f3xx.h"

int main(void)
{
      // Initialize the HSI:
      RCC->CR |= RCC_CR_HSION;
      while(!(RCC->CR&RCC_CR_HSIRDY));

      // Initialize the LSI:
      // RCC->CSR |= RCC_CSR_LSION;
      // while(!(RCC->CSR & RCC_CSR_LSIRDY));

      // PLL configuration:
      RCC->CFGR &= ~RCC_CFGR_PLLSRC;     // HSI / 2 selected as the PLL input clock.
      RCC->CFGR |= RCC_CFGR_PLLMUL16;   // HSI / 2 * 16 = 64 MHz
      RCC->CR |= RCC_CR_PLLON;          // Enable PLL
      while(!(RCC->CR&RCC_CR_PLLRDY));  // Wait until PLL is ready

      // Flash configuration:
      FLASH->ACR |= FLASH_ACR_PRFTBE;
      FLASH->ACR |= FLASH_ACR_LATENCY_1;

      // Main clock output (MCO):
      RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
      GPIOA->MODER |= GPIO_MODER_MODER8_1;
      GPIOA->OTYPER &= ~GPIO_OTYPER_OT_8;
      GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR8;
      GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8;
      GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL0;

      // Output on the MCO pin:
      //RCC->CFGR |= RCC_CFGR_MCO_HSI;
      //RCC->CFGR |= RCC_CFGR_MCO_LSI;
      //RCC->CFGR |= RCC_CFGR_MCO_PLL;
      RCC->CFGR |= RCC_CFGR_MCO_SYSCLK;

      // PLL as the system clock
      RCC->CFGR &= ~RCC_CFGR_SW;    // Clear the SW bits
      RCC->CFGR |= RCC_CFGR_SW_PLL; //Select PLL as the system clock
      while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL); //Wait until PLL is used

      // Bit-bang monitoring:
      RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
      GPIOE->MODER |= GPIO_MODER_MODER10_0;
      GPIOE->OTYPER &= ~GPIO_OTYPER_OT_10;
      GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR10;
      GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10;

      while(1)
      {
          GPIOE->BSRRL |= GPIO_BSRR_BS_10;
          GPIOE->BRR |= GPIO_BRR_BR_10;

      }
}

কোডটি CoIDE V2 এর সাথে জিএনইউ এআরএম এমবেডড টুলচেন -O1 অপ্টিমাইজেশন ব্যবহার করে সংকলিত হয়েছিল। পিন পিএ 8 (এমসিও) এবং পিই 10 এর সংকেতগুলি, একটি অসিস্কোস্কোপ দিয়ে পরীক্ষা করা হয়েছে, এটি দেখতে দেখতে: এখানে চিত্র বর্ণনা লিখুন

এসওয়াইএসসিএলকে সঠিকভাবে কনফিগার করা হয়েছে বলে মনে হচ্ছে, এমসিও (কমলা বক্ররেখা) প্রায় M৪ মেগাহার্টজ (অভ্যন্তরীণ ঘড়ির ত্রুটির মার্জিন বিবেচনা করে) এর দোলনা প্রদর্শন করে। আমার কাছে অদ্ভুত অংশটি হল PE10 (নীল বক্ররেখা) এর আচরণ। অসীমের সময় (1) লুপটিতে প্রাথমিক 3-পদক্ষেপের ক্রিয়াকলাপ (যেমন বিট-সেট / বিট-রিসেট / রিটার্ন) করতে 4 + 4 + 5 = 13 ঘড়ির চক্র লাগে। এটি অন্যান্য অপ্টিমাইজেশনের স্তরে আরও খারাপ হয়ে যায় (উদাঃ -O2, -O3, এআর-ওস): সিগন্যালের নীচের অংশে বেশ কয়েকটি অতিরিক্ত ঘড়ির চক্র যুক্ত করা হয়, যেমন পিই 10 এর পতনশীল এবং ক্রমবর্ধমান প্রান্তগুলির মধ্যে (কোনওভাবে এলএসআই সক্ষম করে মনে হচ্ছে) এই পরিস্থিতিতে প্রতিকার করতে)।

এই আচরণটি কি এই এমসিইউ থেকে প্রত্যাশিত? আমি কোনও কাজটি সেট করার মতোই সহজ কাজটি কল্পনা করব এবং কিছুটা পুনরায় সেট করা 2-4 গুণ দ্রুত হওয়া উচিত। জিনিসগুলি দ্রুত করার কোনও উপায় আছে?


আপনি কি অন্য কিছু এমসিইউর সাথে তুলনা করার চেষ্টা করেছেন?
মার্কো বুরিসি

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

2
কিট দিয়ে দুর্দান্ত শুরু !!
স্কট সিডম্যান

আপনাকে অবশ্যই | = BSRR বা বিআরআর নিবন্ধগুলি কেবল লেখার জন্য নিবন্ধভুক্ত করা উচিত।
পি__জে__

উত্তর:


25

এখানে প্রশ্নটি হ'ল: আপনি সি প্রোগ্রাম থেকে যে মেশিন কোডটি তৈরি করছেন তা কীভাবে হয় এবং আপনি কী আশা করেন তার থেকে এটি কীভাবে আলাদা হয়।

যদি আপনার মূল কোডটিতে অ্যাক্সেস না থাকে, তবে এটি বিপরীত প্রকৌশল (যা মূলত কিছু দিয়ে শুরু করা উচিত radare2 -A arm image.bin; aaa; VV) এর অনুশীলন হত , তবে কোডটি পেয়ে গেছেন যা এটি এত সহজ করে দেয়।

প্রথমে -gপতাকাটিতে যুক্ত করে এটি সংকলন করুন CFLAGS(একই জায়গায় যেখানে আপনি উল্লেখ করেছেন -O1)। তারপরে, উত্পন্ন সমাবেশটি দেখুন:

arm-none-eabi-objdump -S yourprog.elf

লক্ষ্য করুন যে objdumpবাইনারি এবং সেইসাথে আপনার মধ্যবর্তী ELF ফাইলের নাম দুটি আলাদা হতে পারে।

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

আমি আপনার কোডটির কিছুটা প্যাচযুক্ত সংস্করণটি সমাবেশ করেছি :

arm-none-eabi-gcc 
    -O1 ## your optimization level
    -S  ## stop after generating assembly, i.e. don't run `as`
    -I/path/to/CMSIS/ST/STM32F3xx/ -I/path/to/CMSIS/include
     test.c

এবং নিম্নলিখিতগুলি পেয়েছেন (উপরের লিঙ্কের আওতায় পূর্ণ কোড):

.L5:
    ldr r2, [r3, #24]
    orr r2, r2, #1024
    str r2, [r3, #24]
    ldr r2, [r3, #40]
    orr r2, r2, #1024
    str r2, [r3, #40]
    b   .L5

এটি একটি লুপ (শেষে .L5 এবং শুরুর দিকে .L5 লেবেলে নিঃশর্ত লাফ দেখুন)।

আমরা এখানে যা দেখছি তা হ'ল আমরা

  • প্রথমে ldr(লোড রেজিস্ট্রার) + 24 বাইটে r2মেমরির অবস্থানের মান সহ নিবন্ধক করুন r3। খুব সম্ভবত অবস্থান: যে সন্ধান করার খুব অলস হচ্ছে BSRR
  • তারপর ধ্রুব সঙ্গে রেজিস্টার , যা রেজিস্টারে 10th বিট সেট মিলা চাই, এবং ফলাফলের লিখতে নিজেই।ORr21024 == (1<<10)r2
  • তারপরে str(স্টোর) ফলাফলটি প্রথম পদক্ষেপে আমরা পড়েছি এমন মেমরি অবস্থানের মধ্যে
  • এবং তারপরে অলসতার বাইরে, একটি ভিন্ন মেমরি অবস্থানের জন্য একই পুনরাবৃত্তি করুন: সম্ভবত সম্ভাব্য BRRঠিকানা।
  • অবশেষে b(শাখা) প্রথম পদক্ষেপে ফিরে আসুন।

সুতরাং তিনটি নয়, আমাদের কাছে 7 টি নির্দেশ রয়েছে। কেবল bএকবারই ঘটে এবং এর ফলে খুব সম্ভবত একটি বিজোড় সংখ্যক চক্র গ্রহণ করছে (আমাদের মোট ১৩ জন রয়েছে, সুতরাং কোথাও একটি বিজোড় চক্রের গণনা আসতে হবে)। যেহেতু ১৩ এর নীচের সমস্ত বিজোড় সংখ্যা হ'ল 1, 3, 5, 7, 9, 11, এবং আমরা 13-6 এর চেয়ে বড় যে কোনও সংখ্যার রায় বাতিল করতে পারি (ধরে নিই যে সিপিইউ একটি চক্রের চেয়ে কম নির্দেশে নির্দেশনা কার্যকর করতে পারে না ), তাই আমরা জানি যে b1, 3, 5, বা 7 সিপিইউ চক্র লাগে।

আমরা যারা হচ্ছি, আমি এআরএম এর নির্দেশাবলীর ডকুমেন্টেশন এবং এম 3 এর জন্য তারা কতগুলি চক্র গ্রহণ করে তা দেখেছি :

  • ldr 2 চক্র লাগে (বেশিরভাগ ক্ষেত্রে)
  • orr 1 চক্র লাগে
  • str 2 চক্র লাগে
  • b2 থেকে 4 চক্র নেয়। আমরা জানি এটি অবশ্যই একটি বিজোড় সংখ্যা হতে পারে, সুতরাং এটি অবশ্যই এখানে 3 নিতে হবে

আপনার পর্যবেক্ষণের সাথে সমস্ত লাইন আপ:

13=2(R+ +RR+ +গুলিটিR)+ +=2(2+ +1+ +2)+ +3=25+ +3

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

আপনি কি অবশ্যই না পড়া হয় না পারেনি ( |=পরোক্ষভাবে হয়েছে পিন মান যে লুপ পুনরাবৃত্তির, কিন্তু এটি একটি স্থানীয় ভেরিয়েবলের মান লিখুন, যা আপনি শুধু টগল যে লুপ পুনরাবৃত্তির পড়তে)।

খেয়াল করুন যে আমি মনে করি আপনি 8 বিট মাইক্রোসের সাথে পরিচিত হতে পারেন এবং কেবল 8 বিট মান পড়ার চেষ্টা করবেন, স্থানীয় 8 বিট ভেরিয়েবলগুলিতে সংরক্ষণ করুন এবং 8 বিট খণ্ডে এগুলি লিখবেন। না। এআরএম একটি 32 বিট আর্কিটেকচার, এবং 32 বিট শব্দের 8 বিট নিষ্কাশন করা অতিরিক্ত নির্দেশাবলী নিতে পারে। আপনি যদি পারেন তবে কেবল পুরো 32 বিট শব্দটি পড়ুন, আপনার যা প্রয়োজন তা সংশোধন করুন এবং পুরোটি আবার লিখুন। অবশ্যই এটি সম্ভব কিনা আপনি যা লিখছেন তার উপর নির্ভর করে, যেমন আপনার মেমরি-ম্যাপযুক্ত জিপিআইওর লেআউট এবং কার্যকারিতা। আপনি টগল করতে চান বিট 32 বিট মধ্যে কি সঞ্চিত আছে তা তথ্যের জন্য STM32F3 ডাটাশিট / ব্যবহারকারীর গাইডের পরামর্শ নিন।


ঠিক একই লুপ সৌন্দর্য - এখন, আমি "কম" সময়কাল আর পেয়ে সঙ্গে আপনার সমস্যাটি পুনর্গঠন করা চেষ্টা করেছি, কিন্তু আমি কেবল পারিনি -O3মত -O1আমার কম্পাইলার সংস্করণ সহ। আপনাকে নিজেই তা করতে হবে! হতে পারে আপনি সাবসিটিমাল এআরএম সমর্থন সহ জিসিসির কিছু প্রাচীন সংস্করণ ব্যবহার করছেন।


4
আপনি যেভাবে বলেছিলেন, ঠিক ( =পরিবর্তে |=) সংরক্ষণ করা হবে না , ওপি যে স্পিডআপটির সন্ধান করছে তা ঠিকঠাক হবে? এআরএমগুলির বিআরআর এবং বিএসআরআর পৃথকভাবে নিবন্ধভুক্ত হওয়ার কারণ হ'ল পঠন-সংশোধন-লেখার প্রয়োজন নেই। এই ক্ষেত্রে, ধ্রুবকগুলি লুপের বাইরে রেজিস্টারে সংরক্ষণ করা যেতে পারে, সুতরাং অভ্যন্তরীণ লুপটি কেবল 2 স্ট্রের এবং একটি শাখা হবে, তাই পুরো বৃত্তাকার জন্য 2 + 2 +3 = 7 চক্র?
টিমো

ধন্যবাদ। এটি সত্যিই জিনিসগুলিকে বেশ কিছুটা সাফ করেছে। এটি কেবলমাত্র 3 টি ঘড়ির চক্রের প্রয়োজন হবে তা বলার জন্য তাড়াহুড়ো করার চিন্তাভাবনা ছিল - 6 থেকে 7 চক্র এমন কিছু যা আমি আসলে প্রত্যাশা করছিলাম। -O3ত্রুটি পরিষ্কার এবং সমাধান পুনর্নির্মাণ পর উধাও হয়ে গেছে বলে মনে হয়। যাইহোক, আমার সমাবেশ কোডটিতে এটির মধ্যে অতিরিক্ত UTXH নির্দেশনা রয়েছে বলে মনে হচ্ছে: .L5: ldrh r3, [r2, #24] uxth r3, r3 orr r3, r3, #1024 strh r3, [r2, #24] @ movhi ldr r3, [r2, #40] orr r3, r3, #1024 str r3, [r2, #40] b .L5
কেআর

1
uxthআছে কারণ GPIO->BSRRL(ভুলভাবে) আপনার শিরোনামে 16 বিট রেজিস্টার হিসাবে সংজ্ঞায়িত করা হয়েছে। STM32CubeF3 লাইব্রেরি থেকে শিরোনামের একটি সাম্প্রতিক সংস্করণ ব্যবহার করুন , যেখানে কোনও BSRRL এবং BSRRH নেই, তবে একক 32 বিট BSRRরেজিস্টার রয়েছে। @ মার্কাসের স্পষ্টতই সঠিক শিরোনাম রয়েছে, সুতরাং তার কোডটি একটি অর্ধশব্দ লোড এবং এটি প্রসারিত করার পরিবর্তে পুরো 32 বিট অ্যাক্সেস করে।
বেরেন্দি -

কেন একটি একক বাইট লোড অতিরিক্ত নির্দেশাবলী নিতে হবে? এআরএম আর্কিটেকচারটি রয়েছে LDRBএবং STRBযে কোনও একক নির্দেশনায় বাইট পড়ে / লেখেন, না?
স্মৃতি 11

1
M3 কোর করতে বিট-ব্যাণ্ড (নিশ্চিত না এই বিশেষ বাস্তবায়ন হলে), যেখানে পেরিফেরাল মেমরির স্থান একটি 1 মেগাবাইট অঞ্চল 32 মেগাবাইট অঞ্চল ওরফে অন্য সমর্থন করি। প্রতিটি বিটের একটি পৃথক শব্দের ঠিকানা রয়েছে (বিট 0 কেবল ব্যবহৃত হয়)। সম্ভবত কেবল একটি লোড / স্টোরের চেয়ে ধীর।
শান হোলিহানে

8

BSRRএবং BRRরেজিস্টার সেটিং এবং পৃথক বন্দর বিট রিসেট করার জন্য আছেন:

জিপিআইও পোর্ট বিট সেট / রিসেট রেজিস্টার (জিপিআইঅক্স_বিএসআরআর)

...

(x = এ..এইচ) বিট 15: 0

BSy: পোর্ট এক্স সেট বিট y (y = 0..15)

এই বিটগুলি কেবল লেখার জন্য। এই বিটগুলিতে একটি পঠন 0x0000 মান প্রদান করে।

0: সম্পর্কিত ওডিআরএক্স বিটের কোনও পদক্ষেপ নেই

1: সম্পর্কিত ওডিআরএক্স বিট সেট করে

আপনি দেখতে পাচ্ছেন, এই রেজিস্টারগুলি পড়া সর্বদা 0 দেয়, তাই আপনার কোডটি কী

GPIOE->BSRRL |= GPIO_BSRR_BS_10;
GPIOE->BRR |= GPIO_BRR_BR_10;

কার্যকরভাবে নেই GPIOE->BRR = 0 | GPIO_BRR_BR_10, কিন্তু অপটিমাইজার যে জানে না, তাই এটি একটি ক্রম উত্পন্ন LDR, ORR, STRএকটি একক দোকান পরিবর্তে নির্দেশাবলী।

আপনি কেবল লেখার মাধ্যমে ব্যয়বহুল রিড-মডিফাই-রাইটিং অপারেশন এড়াতে পারবেন

GPIOE->BSRRL = GPIO_BSRR_BS_10;
GPIOE->BRR = GPIO_BRR_BR_10;

আপনি কোনও অ্যাড্রেসে লুপটি সারিবদ্ধভাবে আট দ্বারা বিভাজক করে আরও কিছু উন্নতি পেতে পারেন 8 লুপের asm("nop");আগে একটি বা মোড নির্দেশিকা রাখার চেষ্টা করুন while(1)


1

এখানে যা বলা হয়েছে তা যুক্ত করার জন্য: অবশ্যই কর্টেক্স-এম এর সাথে, তবে কোনও প্রসেসরের (একটি পাইপলাইন, ক্যাশে, শাখার পূর্বাভাস বা অন্যান্য বৈশিষ্ট্য সহ) খুব সরল লুপ নেওয়াও তুচ্ছ ial

top:
   subs r0,#1
   bne top

এটি আপনি যতটা মিলিয়ন বার চান তা চালান, তবে সেই লুপটির পারফরম্যান্স ব্যাপকভাবে পরিবর্তিত হতে সক্ষম হোন, কেবল সেই দুটি নির্দেশাবলী, আপনি যদি চান তবে মাঝখানে কিছুটা নপ যুক্ত করুন; এটা কোন ব্যাপার না।

লুপের প্রান্তিককরণটি পরিবর্তনটি নাটকীয়ভাবে পরিবর্তিত হতে পারে, বিশেষত এর মতো একটি ছোট লুপের সাথে যদি এটির পরিবর্তে দুটি আনার জন্য লাইন লাগে তবে আপনি সেই অতিরিক্ত ব্যয়টি খাবেন, এমন কোনও মাইক্রোকন্ট্রোলারে যেখানে ফ্ল্যাশটি 2 দ্বারা সিপিইউর চেয়ে ধীর হয় where অথবা 3 এবং তারপরে ঘড়ির কাঁটা বাড়িয়ে অনুপাতটি অতিরিক্ত আনার চেয়ে 3 বা 4 বা 5 এর চেয়েও খারাপ হয়ে যায়।

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

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

এটি করা কিছুটা তুচ্ছ, এবং একবার আপনি বুঝতে পারলেন যে, তারপর সংকলিত কোড গ্রহণ, এমনকি হাতে লেখা লিখিত সমাবেশ, আপনি দেখতে পারেন যে এর কার্যকারিতা এই কারণগুলির কারণে ব্যাপকভাবে পরিবর্তিত হতে পারে, কয়েক যোগ করতে কয়েক বা কয়েক শতাংশ সংরক্ষণ করে, সি কোডের একটি লাইন, একটি খারাপভাবে রাখা হয়েছে।

বিএসআরআর রেজিস্টারটি ব্যবহার শিখার পরে, ফ্ল্যাশের পরিবর্তে র্যাম (কপি এবং জাম্প) থেকে আপনার কোডটি চালানোর চেষ্টা করুন যা আপনাকে অন্য কিছু না করে এক্সিকিউশনটিতে তাত্ক্ষণিকভাবে 2 থেকে 3 বার কর্মক্ষমতা বাড়িয়ে তুলতে পারে।


0

এই আচরণটি কি এই এমসিইউ থেকে প্রত্যাশিত?

এটি আপনার কোডের আচরণ।

  1. আপনার এখনকার মতো বিআরআর / বিএসআরআর রেজিস্টারগুলিতে লেখা উচিত, পড়ুন-পরিবর্তন করুন-লিখুন না।

  2. আপনি লুপ ওভারহেড ব্যয়। সর্বাধিক কার্য সম্পাদনের জন্য, বিআরআর / বিএসআরআর অপারেশনগুলি বারবার প্রতিলিপি করুন multiple এগুলি একাধিকবার লুপে অনুলিপি করুন এবং পেস্ট করুন যাতে আপনি একটি লুপ ওভারহেডের আগে অনেক সেট / রিসেট চক্রের মধ্য দিয়ে যান।

সম্পাদনা করুন: আইএআর-এর অধীনে কিছু দ্রুত পরীক্ষা করা।

বিআরআর / বিএসআরআরকে লেখার মাধ্যমে একটি ফ্লিপ মাঝারি অপ্টিমাইজেশনের অধীনে instructions টি নির্দেশনা এবং সর্বোচ্চ স্তরের অপ্টিমাইজেশনের অধীনে ৩ টি নির্দেশিকা গ্রহণ করে; আরএমডাব্লু'ংয়ের মাধ্যমে একটি ফ্লিপ 10 টি নির্দেশনা / 6 নির্দেশিকা নেয়।

অতিরিক্ত লুপ লুপ


পরিবর্তন করে |=থেকে =একটি একক বিট সেট / পুনরায় সেট ফেজ 9 ঘড়ি চক্র (হ্রাস লিংক )। সমাবেশ কোডটি 3 টি নির্দেশ দীর্ঘ:.L5 strh r1, [r3, #24] @ movhi str r2, [r3, #40] b .L5
কেআর

1
ম্যানুয়ালি লুপগুলি আনারোল করবেন না । এটি ব্যবহারিকভাবে কখনও ভাল ধারণা নয়। এই বিশেষ ক্ষেত্রে এটি বিশেষত ভয়াবহ: এটি তরঙ্গটি অ-পর্যায়ক্রমিক করে তোলে। এছাড়াও, ফ্ল্যাশে অনেক সময় একই কোড থাকা অগত্যা দ্রুত হয় না। এটি এখানে প্রয়োগ নাও হতে পারে (এটি হতে পারে!) তবে লুপ আন্রোলিং এমন একটি জিনিস যা অনেক লোক মনে করে যে এই সংকলকরা ( gcc -funroll-loops) খুব ভাল করতে পারে এবং যখন আপত্তি দেওয়া হয় (যেমন এখানে) আপনি চান তার বিপরীত প্রভাব রয়েছে।
মার্কাস মুলার 20

একটি সামঞ্জস্যপূর্ণ সময় আচরণ বজায় রাখার জন্য অসীম লুপটি কখনই কার্যকরভাবে তালিকাভুক্ত করা যায় না।
মার্কাস মুলার

1
@ মার্কাসমিলার: লুপের পুনরাবৃত্তির কোনও পয়েন্ট রয়েছে যেখানে কোনও নির্দেশিকার দৃশ্যমান প্রভাব নেই এমন ক্ষেত্রে যদি সামঞ্জস্যপূর্ণ সময় বজায় রাখার ক্ষেত্রে অসীম লুপগুলি কখনও কখনও কার্যকরভাবে তালিকাভুক্ত করা যায় না। উদাহরণস্বরূপ, যদি এমন somePortLatchকোনও পোর্ট নিয়ন্ত্রণ করে যার নীচে 4 বিট আউটপুটের জন্য সেট করা থাকে, তখন কোডটিতে আনারল while(1) { SomePortLatch ^= (ctr++); }করা সম্ভব হতে পারে যা 15 টি মানকে আউটপুট করে এবং তারপরে শুরু করতে লুপ ফিরে আসে যখন অন্যথায় একই মানটি পরপর দু'বার আউটপুট দেয়।
সুপারক্যাট

সুপারকার্যাট, সত্য। এছাড়াও, মেমরি ইন্টারফেসের সময় ইত্যাদির মতো প্রভাবগুলি এটি "আংশিকভাবে" তালিকাভুক্তি থেকে বোধগম্য হতে পারে। আমার বক্তব্যটি খুব সাধারণ ছিল, তবে আমি অনুভব করি যে ড্যানির পরামর্শ আরও সাধারণীকরণ এবং এমনকি বিপজ্জনকভাবে
মারকাস মুলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.