জিসিসি সংকলক কেন কিছু কোড বাদ দিচ্ছে?


9

আমি বুঝতে পারি না কেন জিসিসি সংকলক আমার কোডের কিছু অংশ কাটাচ্ছে যখন এটি আশেপাশে একই রকম সংরক্ষণ করে?

সি কোড:

#define setb_SYNCO do{(PORTA|= (1<<0));} while(0);

ISR(INT0_vect){
    unsigned char i;

    i = 10;
    while(i>0)i--;   // first pause - omitted

    setb_SYNCO;
    setb_GATE;
    i=30;
    clrb_SYNCO;
    while(i>0)i--;  // second pause - preserved
    clrb_GATE;
}

LSS এর সংশ্লিষ্ট অংশ (সংকলক দ্বারা তৈরি করা এসেমব্লার ফাইল):

ISR(INT0_vect){
  a4:   1f 92           push    r1
  a6:   0f 92           push    r0
  a8:   0f b6           in  r0, 0x3f    ; 63
  aa:   0f 92           push    r0
  ac:   11 24           eor r1, r1
  ae:   8f 93           push    r24
    unsigned char i;

    i = 10;
    while(i>0)i--;

    setb_SYNCO;
  b0:   d8 9a           sbi 0x1b, 0 ; 27
    setb_GATE;
  b2:   d9 9a           sbi 0x1b, 1 ; 27
    i=30;
    clrb_SYNCO;
  b4:   d8 98           cbi 0x1b, 0 ; 27
  b6:   8e e1           ldi r24, 0x1E   ; 30
  b8:   81 50           subi    r24, 0x01   ; 1
    while(i>0)i--;
  ba:   f1 f7           brne    .-4         ; 0xb8 <__vector_1+0x14>
    clrb_GATE;
  bc:   d9 98           cbi 0x1b, 1 ; 27
}
  be:   8f 91           pop r24
  c0:   0f 90           pop r0
  c2:   0f be           out 0x3f, r0    ; 63
  c4:   0f 90           pop r0
  c6:   1f 90           pop r1
  c8:   18 95           reti

আমি ধরে নিতে পারি যে সংকলকটি বুঝতে পারে যে এই জাতীয় কোডটি ডামি এবং এটি কেটে দেয় তবে কেন কোডের শেষে এটি একইটিকে সংরক্ষণ করা হচ্ছে?

এই ধরনের অপ্টিমাইজেশন থেকে রোধ করার জন্য কি কোনও সংকলক নির্দেশাবলী রয়েছে?


1
আপনি একক ফাংশনটি অপ্টিমাইজ না করার জন্যও সংকলকটিকে বলতে পারেন, সম্ভবত আপনার আইএসআর দিয়ে এই পদ্ধতিটি চেষ্টা করা ভাল worth দেখুন এই Stackoverflow উপর প্রশ্ন।
ভ্লাদিমির ক্র্যাভারো

2
আরে রোমান, আমি আপনার প্রশ্নের সাথে অ্যামেগা সরিয়ে "সি" ট্যাগ যুক্ত করেছি। সীমাবদ্ধতা (পাঁচ) থাকার কারণে আমাকে একটি ট্যাগ সরিয়ে ফেলতে হয়েছিল এবং ভাষা সংক্রান্ত নামটি ট্যাগ হিসাবে যুক্ত করার সাথে কোড সম্পর্কিত প্রশ্ন জিজ্ঞাসা করা দুর্দান্ত কারণ সমস্ত কোড (প্রশ্নোত্তর হিসাবে) হাইলাইট হয়ে যায়।
ভ্লাদিমির ক্র্যাভারো

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

5
আরও ভাল প্রশ্ন হ'ল, জিসিসি কেন এই দুটি লুপকে অপ্টিমাইজ করছে না ?
ইলমারি করোনেন

5
জিসিসি প্রথমে লুপটিকে আনআরলস করে এবং তারপরেই লক্ষ্য করে যে সংশ্লিষ্ট কোডটি অকেজো। 30 এর লুপের আকারের সাথে, আনআরোলিং করা বোকামি হবে এবং জিসিসি এটি করে না। উচ্চতর অপ্টিমাইজেশনের স্তরে উভয়ই অপটিমাইজ করা হয়।
মার্ক গ্লিস

উত্তর:


9

যেহেতু একটি মন্তব্যে আপনি লিখেছেন যে "প্রতিটি সিপিইউ টিক যোগ্য" আমি আপনার বিলম্ব লুপটি যেমন চাই তেমন করতে কিছু ইনলাইন সমাবেশ ব্যবহার করার পরামর্শ দিচ্ছি। এই সমাধানটি বিভিন্নের চেয়ে সেরা volatileবা -O0কারণ এটি আপনার উদ্দেশ্য কী তা স্পষ্ট করে

unsigned char i = 10;
__asm__ volatile ( "loop: subi    %0, 0x01\n\t"
                   "      brne    loop"
                   : "+rm" (i)
                   : /* no inputs */
                   : /* no dirty registers to decleare*/);

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

ওপির অনুরোধ অনুসারে সম্পাদিত উত্তর সম্পাদনা করুন । কিছু নোট।

"+rm"সামনে (i)মানে আপনি কম্পাইলার লেট হয় আমি স্থান করার সিদ্ধান্ত নেন মি Emory বা মধ্যে R egister। এটি বেশিরভাগ ক্ষেত্রেই খুব ভাল বিষয় যেহেতু সংকলকটি এটি নিখরচায় থাকলে আরও ভাল অনুকূল করতে পারে। আপনার ক্ষেত্রে আমি বিশ্বাস করি যে আমি রেজিস্টার হতে বাধ্য করার জন্য আপনি কেবলমাত্র বাধা রাখতে চান।


দেখে মনে হচ্ছে এটি সত্যই আমার প্রয়োজন। তবে আপনি মূল cউত্তরটিতে 10উল্লিখিত আক্ষরিক পরিবর্তে কোনও পরিবর্তনকে গ্রহণ করার জন্য আপনার উত্তরটি পরিবর্তন করতে পারেন ? আমি asm নির্মাণের সঠিক ব্যবহার সম্পর্কে জিসিসি ম্যানুয়ালগুলি পড়ার চেষ্টা করছি তবে এটি এখন আমার কাছে কিছুটা অস্পষ্ট। আমি খুব প্রশংসা করব!
রোমান মতভীভ

1
আপনার অনুরোধ অনুসারে @ রোমানমাতভীভ সম্পাদনা করেছেন
ভ্লাদিমির ক্র্যাভারো

13

আপনি লুপটি আসলে কিছু করার চেষ্টা করতে পারেন। সংকলকটি যথাযথভাবে বলছে "এই লুপটি কিছুই করছে না - আমি এ থেকে মুক্তি পাব"।

সুতরাং আপনি এমন একটি নির্মাণের চেষ্টা করতে পারেন যা আমি প্রায়শই ব্যবহার করি:

int i;
for (i = 0; i < 10; i++) {
    asm volatile ("nop");
}

দ্রষ্টব্য: জিসিসি সংকলকটির জন্য সমস্ত টার্গেট একই ইনলাইনে বিধানসভা সিনট্যাক্স ব্যবহার করে না - আপনার টার্গেটের জন্য আপনাকে এটি টুইট করতে হবে।


আপনার সমাধানটি আমার চেয়ে অনেক বেশি মার্জিত বলে মনে হচ্ছে ... যখন চক্র গণনার প্রয়োজন হয় তখন আমার কি আরও ভাল হয়? আমি বলতে চাইছি, পুরো জিনিসটি নির্দিষ্ট উপায়ে সংকলনের গ্যারান্টিযুক্ত নয়, তাই না?
ভ্লাদিমির ক্র্যাভারো

8
এটি সি ব্যবহার করার সহজ বিষয়টির অর্থ আপনি চক্রের গ্যারান্টি দিতে পারবেন না। আপনার যদি সুনির্দিষ্ট চক্র গণনার প্রয়োজন হয় তবে এএসএমই একমাত্র উপায়। মানে, সি-লুপের সাথে আপনি আলাদা সময় পাবেন যদি আপনার ফুনারল-লুপগুলি সক্ষম না হয় তার চেয়ে বেশি সক্ষম থাকে ইত্যাদি।
মাজনকো

হ্যাঁ এটাই আমি ভেবেছিলাম। উচ্চ পর্যায়ে আমি মানগুলি (100 বা ততোধিক) সহ এইচডাব্লুয়াদে বিলম্ব করার সময় আমি অনুমান করি যে পাঠযোগ্যতা বাড়ানোর সময় আপনার সমাধানটি কার্যত একই ফলন দেয়।
ভ্লাদিমির ক্র্যাভেরো 26'15

6

হ্যাঁ আপনি ধরে নিতে পারেন। আপনি যদি ভেরিয়েবল i কে অস্থির হিসাবে ঘোষণা করেন তবে আপনি সংকলককে বলবেন যে আমি অপ্টিমাইজ না করবো।


1
এটি আমার মতে পুরোপুরি সত্য নয়।
ভ্লাদিমির ক্র্যাভারো

1
@ ভ্লাদিমিরক্রেরো, এই কথাটি বলতে কী বোঝ? আপনি আরও পরিষ্কার করতে পারেন?
রোমান মতভীভ

2
আমি যা বোঝাতে চেয়েছি তা হল যে কোনও সংকলক কী করবে সে সম্পর্কে আমি এতটা নিশ্চিত নই। একটি পরিবর্তনশীল অস্থির ঘোষণা ঘোষক সংকলককে বলে যে এটি অন্য কোথাও পরিবর্তিত হতে পারে তাই এটি আসলেই হওয়া উচিত।
ভ্লাদিমির ক্র্যাভারো

1
@ রোমান মাত্তিভ register unsigned char volatile i __asm__("r1");হয়ত?
a3f

2
iঅস্থির হিসাবে ঘোষণা করা সবকিছু সমাধান করে। এটি সি স্ট্যান্ডার্ড 5.1.2.3 দ্বারা গ্যারান্টিযুক্ত। যদি কোনও iপরিবর্তনশীল হয় তবে একটি সংযোজনকারী সংকলক অবশ্যই সেই লুপগুলি অপ্টিমাইজ করবেন না । ভাগ্যক্রমে, জিসিসি একটি মাননীয় সংকলক। দুর্ভাগ্যক্রমে অনেকগুলি সি-সংকলক রয়েছে যা মানের সাথে খাপ খায় না, তবে এটি এই বিশেষ প্রশ্নের জন্য অপ্রাসঙ্গিক। ইনলাইন এসেম্বলারের কোনও প্রয়োজন নেই need
লুন্ডিন

1

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

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

আমি মনে করি iযে আপনি কোনও (অস্বচ্ছ) বন্দর অ্যাক্সেসকে প্রভাবিত করতে পারে সেজন্য জিসিসি সম্পূর্ণরূপে রাখে i

ব্যবহার

asm volatile ("nop");

লুপটি কিছু করে এই বিশ্বাসে জিসিসিকে চালিত করতে।

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