<কি <= এর চেয়ে দ্রুত?


1574

কি if( a < 901 )যতো তাড়াতাড়ি if( a <= 900 )

এই সাধারণ উদাহরণের মতো ঠিক নয় তবে লুপ জটিল কোডে সামান্য পারফরম্যান্সের পরিবর্তন রয়েছে। আমি মনে করি এটি জেনারেটেড মেশিন কোড সহ কিছু করতে হবে যদি এটি এমনকি সত্য হয়।


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

32
আপনি কোন বইটি উল্লেখ করছেন তা কখনই আমাদের জানাননি ।
জোনাথন রাইনহার্ট

159
টাইপিং <টাইপিংয়ের চেয়ে দ্বিগুণ দ্রুত <=
Deqing

6
এটি 8086
জোশুয়া

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

উত্তর:


1703

না, বেশিরভাগ আর্কিটেকচারে এটি দ্রুত হবে না। আপনি নির্দিষ্ট করেন নি, তবে x86 এ সমস্ত অবিচ্ছেদ্য তুলনা দুটি মেশিনের নির্দেশে সাধারণত প্রয়োগ করা হবে:

  • একটি testবা cmpনির্দেশ, যা সেট করেEFLAGS
  • এবং তুলনামূলক ধরণের (এবং কোড লেআউট) উপর নির্ভর করে একটি Jcc(জাম্প) নির্দেশনা :
    • jne - সমান না হলে ঝাঁপ দাও -> ZF = 0
    • jz - শূন্য হলে সমান (সমান) -> ZF = 1
    • jg - আরও বেশি হলে লাফ দিন -> ZF = 0 and SF = OF
    • (ইত্যাদি ...)

উদাহরণ (ব্রেভিটির জন্য সম্পাদিত) এর সাথে সংকলিত$ gcc -m32 -S -masm=intel test.c

    if (a < b) {
        // Do something 1
    }

সংকলন:

    mov     eax, DWORD PTR [esp+24]      ; a
    cmp     eax, DWORD PTR [esp+28]      ; b
    jge     .L2                          ; jump if a is >= b
    ; Do something 1
.L2:

এবং

    if (a <= b) {
        // Do something 2
    }

সংকলন:

    mov     eax, DWORD PTR [esp+24]      ; a
    cmp     eax, DWORD PTR [esp+28]      ; b
    jg      .L5                          ; jump if a is > b
    ; Do something 2
.L5:

সুতরাং উভয়ের মধ্যে কেবলমাত্র পার্থক্য হ'ল jgবনাম একটি jgeনির্দেশনা। দু'জন একই পরিমাণ সময় নিবে।


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

অদৃশ্যতা - যে মৃত্যুদন্ড কোর জন্য প্রয়োজন হয় ঘড়ি চক্র সংখ্যা μops যে একটি নির্দেশ গঠন সব সঞ্চালনের সম্পূর্ণ করতে।

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

এর মানগুলি হ'ল Jcc:

      Latency   Throughput
Jcc     N/A        0.5

নিম্নলিখিত পাদটীকা সহ Jcc:

)) শর্তসাপেক্ষে ভবিষ্যদ্বাণীকে উন্নত করার জন্য শর্তসাপেক্ষে জাম্প নির্দেশাবলী নির্বাচন বিভাগের ৩.৪.১, "শাখা পূর্বাভাস অনুকূলকরণ," এর সুপারিশের ভিত্তিতে হওয়া উচিত। যখন শাখাগুলি সফলভাবে পূর্বাভাস দেওয়া হয়, তখন এর প্রচ্ছন্নতা jccকার্যকরভাবে শূন্য হয়।

সুতরাং, ইন্টেল ডক্সের কোনও কিছুই কখনই Jccকোনও নির্দেশকে অন্যের চেয়ে আলাদা আচরণ করে না।

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


সম্পাদনা: ভাসমান পয়েন্ট

এটি এক্স ৮87৯ এর ভাসমান পয়েন্টের ক্ষেত্রেও সত্য: (উপরের মতো অনেকগুলি একই কোডের doubleপরিবর্তে , তবে এর পরিবর্তে int))

        fld     QWORD PTR [esp+32]
        fld     QWORD PTR [esp+40]
        fucomip st, st(1)              ; Compare ST(0) and ST(1), and set CF, PF, ZF in EFLAGS
        fstp    st(0)
        seta    al                     ; Set al if above (CF=0 and ZF=0).
        test    al, al
        je      .L2
        ; Do something 1
.L2:

        fld     QWORD PTR [esp+32]
        fld     QWORD PTR [esp+40]
        fucomip st, st(1)              ; (same thing as above)
        fstp    st(0)
        setae   al                     ; Set al if above or equal (CF=0).
        test    al, al
        je      .L5
        ; Do something 2
.L5:
        leave
        ret

239
@ ডিপ্পল আসলে jgএবং jnleএকই নির্দেশনা, 7F:-)
জোনাথন রেইনহার্ট

17
অপ্টিমাইজার কোডটি সংশোধন করতে পারে তা উল্লেখ করার দরকার নেই যদি সত্যিই একটি বিকল্প অপরের চেয়ে দ্রুত হয়।
এলাজার লাইবোভিচ

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

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

2
@ জোন্টেজ আপনি একটি খুব ভাল বিষয় তৈরি করেছেন make এই উত্তরটি যতটা দৃশ্যমান হয়, তার জন্য আমার এটি সম্ভবত একটি পরিষ্কার করা উচিত। সাহায্য করার জন্য ধন্যবাদ.
জোনাথন রেইনার্ট

593

Icallyতিহাসিকভাবে (আমরা 1980 এর দশক এবং 1990 এর দশকের প্রথম দিকে কথা বলছিলাম), কিছু স্থাপত্য ছিল যা এটি সত্য ছিল this মূল সমস্যাটি হ'ল পূর্ণসংখ্যা তুলনা সহজাতভাবে পূর্ণসংখ্যা বিয়োগের মাধ্যমে প্রয়োগ করা হয়। এটি নিম্নলিখিত ক্ষেত্রে উত্থাপন দেয়।

Comparison     Subtraction
----------     -----------
A < B      --> A - B < 0
A = B      --> A - B = 0
A > B      --> A - B > 0

A < Bবিয়োগফলকে সঠিক হওয়ার জন্য এখন যখন বিয়োগফলকে একটি উচ্চ-বিট orrowণ নিতে হবে, ঠিক তেমনি আপনি হাতের যোগ এবং বিয়োগের সময় যখন বহন করেন এবং ধার করেন। এই "ধার করা" বিটটি সাধারণত ক্যারি বিট হিসাবে উল্লেখ করা হত এবং এটি একটি শাখার নির্দেশের দ্বারা পরীক্ষাযোগ্য হবে। শূন্য বিট নামক একটি দ্বিতীয় বিট সেট করা হবে যদি বিয়োগটি একইভাবে শূন্য হয় যা সাম্যকে বোঝায়।

সাধারণত কমপক্ষে দুটি শর্তাধীন শাখার নির্দেশনা ছিল, একটি ক্যারি বিটে শাখা করা এবং শূন্য বিটের একটি one

এখন বিষয়টির কেন্দ্রবিন্দুতে পেতে, চলুন এবং শূন্য বিটের ফলাফলগুলি অন্তর্ভুক্ত করতে আগের টেবিলটি প্রসারিত করুন।

Comparison     Subtraction  Carry Bit  Zero Bit
----------     -----------  ---------  --------
A < B      --> A - B < 0    0          0
A = B      --> A - B = 0    1          1
A > B      --> A - B > 0    1          0

সুতরাং, একটি শাখা বাস্তবায়ন A < B, এক নির্দেশ মধ্যে সম্পন্ন করা যাবে না কারণ বহন বিট স্পষ্ট শুধুমাত্র এই ক্ষেত্রে,, যে,

;; Implementation of "if (A < B) goto address;"
cmp  A, B          ;; compare A to B
bcz  address       ;; Branch if Carry is Zero to the new address

তবে, আমরা যদি তুলনামূলক কম বা সমান তুলনা করতে চাই, সাম্যের ক্ষেত্রে এটি ধরতে আমাদের শূন্য পতাকাটির একটি অতিরিক্ত চেক করতে হবে।

;; Implementation of "if (A <= B) goto address;"
cmp A, B           ;; compare A to B
bcz address        ;; branch if A < B
bzs address        ;; also, Branch if the Zero bit is Set

সুতরাং, কিছু মেশিনে, "কম" তুলনা ব্যবহার করা হলে একটি মেশিনের নির্দেশনা সংরক্ষণ করতে পারে । এটি সাব-মেগাহের্টজ প্রসেসরের গতি এবং 1: 1 সিপিইউ-থেকে-মেমরি গতির অনুপাতের যুগে প্রাসঙ্গিক ছিল, তবে এটি আজ প্রায় সম্পূর্ণ অপ্রাসঙ্গিক।


10
অতিরিক্তভাবে, x86 এর মতো আর্কিটেকচার নির্দেশাবলী কার্যকর করে যেমন jgeশূন্য এবং সাইন / পতাকা উভয়ই পরীক্ষা করে।
গ্রেফ্যাড

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

8
এটি 8080-এ সত্য It

4
এটি 6502 এবং 65816 প্রসেসর পরিবারের ক্ষেত্রেও হয়, এটি মোটরোলা 68HC11 / 12 পর্যন্তও প্রসারিত।
লুকাস

31
এমনকি 8080 উপর একটি <=পরীক্ষা বাস্তবায়ন করা যায় এক operands সোয়াপিং এবং জন্য পরীক্ষাটি নির্দেশ not <(সমতুল্য করার >=) এই আকাঙ্ক্ষিত হয় <=অদলবদল operands সঙ্গে cmp B,A; bcs addr। এই কারণেই এই পরীক্ষাটি ইন্টেল বাদ দিয়েছিল, তারা এটিকে অপ্রয়োজনীয় বলে বিবেচনা করে এবং আপনি সেই সময়ে অপ্রয়োজনীয় নির্দেশাবলীর পক্ষে বহন করতে পারেন না :-)
গুন্থার পাইজ

92

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

যদি এমন কিছু প্ল্যাটফর্ম থাকে যেখানে সাধারণ পূর্ণসংখ্যার ধরণের <চেয়ে দ্রুত ছিল <=, সংকলকটি সর্বদা ধ্রুবকগুলির জন্য রূপান্তর <=করা উচিত <। যে কোনও সংকলক কেবল খারাপ সংকলক হবে না (সেই প্ল্যাটফর্মের জন্য)।


6
+1 আমি সম্মত আমরাও <না <=যতক্ষণ না কম্পাইলার সিদ্ধান্ত নেয় যা গতি তারা থাকবে গতি আছে। সংকলকগুলির জন্য এটি একটি খুব সাধারণ অপ্টিমাইজেশন যখন আপনি বিবেচনা করেন যে তারা সাধারণত ডেড কোড অপটিমাইজেশন, টেল কল অপ্টিমাইজেশন, লুপ উত্তোলন (এবং আনরোলিং, বিভিন্ন উপলক্ষে), বিভিন্ন লুপের স্বয়ংক্রিয় সমান্তরালকরণ ইত্যাদি ... কেন সময় নষ্ট করে অকাল অপ্টিমাইজেশন ? একটি প্রোটোটাইপ দৌড়ে আসুন, সর্বাধিক উল্লেখযোগ্য অপ্টিমাইজেশন কোথায় রয়েছে তা নির্ধারণ করতে এটি প্রোফাইল করুন, অগ্রগতি পরিমাপের পথে আবারও তাৎপর্য এবং প্রোফাইলের জন্য সেই অপটিমাইজেশন সম্পাদন করুন ...
অটিস্টিক

এখনও কিছু প্রান্ত ক্ষেত্রে যেখানে একটি তুলনা একটি ধ্রুবক মান অধীনে মন্থর হতে পারে <=, যেমন, যখন থেকে রূপান্তর (a < C)করতে (a <= C-1)(কিছু ধ্রুবক জন্য C) ঘটায় Cনির্দেশ সেটে সঙ্কেতাক্ষরে লিখা আরো কঠিন হবে। উদাহরণস্বরূপ, কোনও নির্দেশিকা সেট তুলনা করে একটি কমপ্যাক্ট ফর্মের মধ্যে -127 থেকে 128 পর্যন্ত স্বাক্ষরিত ধ্রুবকগুলিকে উপস্থাপন করতে সক্ষম হতে পারে, তবে এই সীমার বাইরে স্থিরকারীরা দীর্ঘতর, ধীর এনকোডিং বা অন্য কোনও নির্দেশ পুরোপুরিভাবে লোড করতে হয়। সুতরাং মত তুলনা (a < -127)একটি সরল রূপান্তর হতে পারে না।
BeeOnRope

@ বিঅনরোপ এই সমস্যাটি ছিল না যে তাদের মধ্যে বিভিন্ন ধ্রুবক থাকার কারণে পার্থক্য করা অপারেশনগুলি পারফরম্যান্সকে প্রভাবিত করতে পারে কিনা তবে ভিন্ন ধ্রুবক ব্যবহার করে একই ক্রিয়াকলাপটি প্রকাশ করা কার্য সম্পাদনকে প্রভাবিত করতে পারে কিনা তা নয় । সুতরাং আমরা তুলনা করছি না করার কারণ আপনার কোন উপায় আছে আছে, তবে আপনি আপনার প্রয়োজনীয় কোনো একটিকে ব্যবহার করুন। আমরা তুলনা করছেন করার , যা বিভিন্ন এনকোডিং বা বিভিন্ন নির্দেশাবলী প্রয়োজন পারবেন না কারণ তারা একই সত্য টেবিল আছে। যেকোন একটির এনকোডিং অন্যটির সমান এনকোডিং। a > 127a > 128a > 127a >= 128
ডেভিড শোয়ার্টজ

আমি আপনার বক্তব্যের একটি সাধারণ উপায়ে প্রতিক্রিয়া জানিয়েছিলাম যে "" যদি এমন কিছু প্ল্যাটফর্ম থাকে যেখানে [<= ধীর ছিল] কম্পাইলারটি সর্বদা ধ্রুবকগুলির জন্য রূপান্তরিত <=হয় <"। আমি যতদূর জানি, সেই রূপান্তরটির মধ্যে ধ্রুবক পরিবর্তন জড়িত। উদাহরণস্বরূপ, a <= 42সংকলিত a < 43কারণ <দ্রুত হয়। কিছু প্রান্তের ক্ষেত্রে, এই ধরনের রূপান্তর ফলপ্রসূ হবে না কারণ নতুন ধ্রুবকটির আরও বা ধীর নির্দেশের প্রয়োজন হতে পারে। অবশ্যই a > 127এবং a >= 128সমতুল্য এবং একটি সংকলক উভয় ফর্মকে (একই) দ্রুততম উপায়ে এনকোড করা উচিত, তবে আমি যা বলেছিলাম তার সাথে এটি বেমানান নয়।
BeeOnRope

67

আমি দেখতে পাচ্ছি যে দুটিও দ্রুত নয়। সংকলক পৃথক মান সহ প্রতিটি শর্তে একই মেশিন কোড উত্পন্ন করে।

if(a < 901)
cmpl  $900, -4(%rbp)
jg .L2

if(a <=901)
cmpl  $901, -4(%rbp)
jg .L3

আমার উদাহরণটি ifলিনাক্সের x86_64 প্ল্যাটফর্মের জিসিসি থেকে।

সংকলক লেখকরা বেশ স্মার্ট ব্যক্তি এবং তারা এই বিষয়গুলি সম্পর্কে চিন্তা করে এবং আমাদের মধ্যে অনেককেই সম্মতি দেওয়া হয়।

আমি লক্ষ্য করেছি যে এটি যদি ধ্রুবক না হয় তবে একই মেশিন কোডটি উভয় ক্ষেত্রেই উত্পন্ন হয়।

int b;
if(a < b)
cmpl  -4(%rbp), %eax
jge   .L2

if(a <=b)
cmpl  -4(%rbp), %eax
jg .L3

9
নোট করুন যে এটি x86 এর সাথে নির্দিষ্ট।
মাইকেল পেট্রোটা

10
আমি মনে করি আপনার এটি ব্যবহার করা উচিত if(a <=900)এটি প্রদর্শন করতে যে এটি ঠিক একই asm জেনারেট করে :)
লিপিস

2
@ অ্যাড্রিয়ান কর্নিশ দুঃখিত .. আমি এটি সম্পাদনা করেছি .. এটি কমবেশি একই রকম .. তবে আপনি যদি দ্বিতীয়টি পরিবর্তন করেন তবে <= 900 হয় তবে এসএম কোডটি ঠিক একই রকম হবে :) এটি এখন বেশ একইরকম .. তবে আপনি জেনে নিন .. ওসিডির জন্য :)
লিপিস

3
@ বুনান এটিকে হ্রাস করতে পারে (সত্য হলে) এবং সম্পূর্ণরূপে নির্মূল করা।
কিসারিও

5
কেউ চিহ্নিত করেন নি যে এই অপটিমাইজেশনটি কেবল ধ্রুবক তুলনাগুলিতে প্রযোজ্য । আমি গ্যারান্টি দিতে পারি যে দুটি ভেরিয়েবলের তুলনা করার জন্য এটি এর মতো করা হবে না
জোনাথন রেইনহার্ট

51

ভাসমান পয়েন্ট কোডের জন্য, আধুনিক আর্কিটেকচারে <= তুলনা সত্যই ধীর হতে পারে (এক নির্দেশ অনুসারে)। এখানে প্রথম ফাংশন:

int compare_strict(double a, double b) { return a < b; }

পাওয়ারপিসিতে প্রথমে এটি একটি ভাসমান পয়েন্ট তুলনা সম্পাদন করে (যা আপডেট করে cr, শর্ত রেজিস্ট্রার করে), তারপরে শর্তটি রেজিস্টারকে একটি জিপিআরে স্থানান্তরিত করে, "তুলনায় কম" স্থানে স্থানান্তরিত করে এবং তারপরে ফিরে আসে। এটি চারটি নির্দেশাবলী লাগে।

পরিবর্তে এখন এই ফাংশনটি বিবেচনা করুন:

int compare_loose(double a, double b) { return a <= b; }

এটির জন্য compare_strictউপরের মতো একই কাজ করা প্রয়োজন তবে এখন দুটি আগ্রহের বিট রয়েছে: "" "এর চেয়ে কম ছিল" এবং "সমান ছিল" " এই crorদুটি বিট একসাথে একত্রিত করার জন্য এটির জন্য অতিরিক্ত নির্দেশের প্রয়োজন ( - শর্তটি বিটওয়াইজ OR বা)। সুতরাং compare_looseপাঁচটি নির্দেশিকা প্রয়োজন, যখন compare_strictচারটি প্রয়োজন।

আপনি ভাবতে পারেন যে সংকলকটি দ্বিতীয় ফাংশনটি এর মতো অনুকূল করতে পারে:

int compare_loose(double a, double b) { return ! (a > b); }

তবে এটি NaN গুলি ভুলভাবে পরিচালনা করবে। NaN1 <= NaN2এবং NaN1 > NaN2উভয়েরই ভুয়া মূল্যায়ন করা দরকার।


ভাগ্যক্রমে এটি x86 (x87) এর মতো কাজ করে না। fucomipজেডএফ এবং সিএফ সেট করে
জোনাথন রেইনহার্ট

3
@JonathonReinhart: আমি আপনি কি মনে করেন করছি ভুল বোঝাবুঝি কি পাওয়ারপিসি করছে - শর্ত রেজিস্টার cr হল মত পতাকা সমতূল্য ZFএবং CFএক্স 86 উপর। (যদিও সিআরটি আরও নমনীয়)
ডায়েটারিচ এপ্প

@ ডায়েটরিচএপ আমার বক্তব্যটি যুক্ত করার পরে আমি কী বোঝাতে চাইছিলাম তা: এটি আপনি তত্ক্ষণাত এএফএলএগএস এর মানের ভিত্তিতে ঝাঁপিয়ে পড়তে পারেন। পরিষ্কার না হওয়ার জন্য দুঃখিত।
জোনাথন রাইনহার্ট

1
@ জোনাথনরাইনহার্ট: হ্যাঁ, এবং আপনি সিআর এর মানের ভিত্তিতে অবিলম্বে ঝাঁপিয়ে পড়তে পারেন। উত্তরটি জাম্পিংয়ের কথা বলছে না, এখান থেকে অতিরিক্ত নির্দেশাবলী এসেছে।
ডায়েটারিচ এপ্প

34

হয়ত সেই নামবিহীন বইটির লেখক পড়েছেন যা তার a > 0চেয়ে দ্রুত চলেa >= 1 এবং মনে করে যে এটি সর্বজনীনভাবে সত্য।

তবে এটি কোনও কারণের 0সাথে জড়িত থাকার কারণে (কারণ CMPআর্কিটেকচারের উপর নির্ভর করে, যেমন প্রতিস্থাপন করা যেতে পারে OR) এবং এর কারণে নয় <


1
অবশ্যই, একটি "ডিবাগ" বিল্ডে, তবে এটি (a >= 1)ধীরে ধীরে চলতে খারাপ সংকলক লাগবে (a > 0), যেহেতু পূর্ববর্তীটি অপেক্ষাকৃত অপ্টিমাইজারের মাধ্যমে পরের দিকে তুচ্ছভাবে রূপান্তরিত হতে পারে ..
BeeOnRope

2
@ বিঅনরোপ কখনও কখনও আমি অবাক হয়ে যাই যে কোনও অপ্টিমাইজার কী জটিল জিনিসগুলি অনুকূল করতে পারে এবং কোন সহজ জিনিস এটি করতে ব্যর্থ হয়।
glglgl

1
প্রকৃতপক্ষে, এবং এটি সর্বদা খুব কম ফাংশনগুলির জন্য asm আউটপুট যাচাই করার জন্য মূল্যবান। এটি বলেছিল যে উপরের রূপান্তরটি খুব মৌলিক এবং কয়েক দশক ধরে এমনকি সাধারণ সংকলকগুলিতে এটি সম্পাদিত হয়েছে।
BeeOnRope

32

খুব কমপক্ষে, যদি এটি সত্য হয় তবে কোনও সংকলক তুচ্ছভাবে কোনও <= b থেকে! ।


কেন! (A> খ) একটি <= b এর অনুকূলিত সংস্করণ। না! (A> খ) এক মধ্যে 2 অপারেশন?
অভিষেক সিং

6
@ অভিষেকসিংহ NOTসবেমাত্র অন্যান্য নির্দেশাবলী দ্বারা তৈরি করা হয়েছে ( jeবনাম jne)
পাভেল গাতনার

15

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


14

এটি সি অন্তর্ভুক্ত আর্কিটেকচারের উপর নির্ভর করবে। কিছু প্রসেসর এবং আর্কিটেকচারের সমান বা তার চেয়ে কম বা সমান অংশের জন্য স্পষ্ট নির্দেশাবলী থাকতে পারে, যা বিভিন্ন সংখ্যায় চক্র চালায়।

এটি যদিও খুব অস্বাভাবিক হবে কারণ সংকলকটি এটি প্রায় অপ্রাসঙ্গিক করে তোলে, এটি চারপাশে কাজ করতে পারে।


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

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

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

12

টিএল; ডিআর উত্তর

আর্কিটেকচার, সংকলক এবং ভাষার বেশিরভাগ সংমিশ্রণের জন্য এটি দ্রুত হবে না।

পুরো উত্তর

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

এই হিসাবে, আমি পরামর্শ দেব যে এই ধরণের মাইক্রো-অপ্টিমাইজেশন সেরা সফ্টওয়্যার ইঞ্জিনিয়ারিং অনুশীলনের চেয়ে কার্গো কাল্ট প্রোগ্রামিংয়ের একটি উদাহরণ ।

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

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

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


6

কোনও কিছু থাকলেও আপনি পার্থক্যটি লক্ষ্য করতে সক্ষম হবেন না। এছাড়াও, অনুশীলনে, আপনাকে একটি অতিরিক্ত কাজ করতে হবে a + 1বা a - 1শর্তটি দাঁড় করাতে হবে যদি না আপনি কোনও ম্যাজিক ধ্রুবক ব্যবহার না করেন যা কোনওভাবেই খুব খারাপ অভ্যাস।


1
খারাপ অনুশীলন কি? কাউন্টার বাড়ানো বা হ্রাস করা? আপনি কীভাবে সূচক চিহ্নিতকরণ সংরক্ষণ করবেন?
jcolebrand

5
তার অর্থ যদি আপনি 2 পরিবর্তনশীল প্রকারের তুলনা করছেন। আপনি যদি লুপ বা কোনও কিছুর জন্য মান নির্ধারণ করেন তবে অবশ্যই এটি তুচ্ছ। তবে আপনার যদি x <= y, এবং y অজানা থাকে তবে এটি x <y + 1 এ 'অনুকূলিতকরণ' করতে ধীর হবে
জাস্টিনডানিয়েলসন

@ জাস্টিনডানিয়েলসন সম্মত হয়েছেন কুরুচিপূর্ণ, বিভ্রান্তিকর ইত্যাদির উল্লেখ না করা
জোনাথন রাইনহার্ট

4

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


আমি কিছুটা দ্বিমত পোষণ করি। প্রতিযোগিতামূলক প্রোগ্রামিংয়ে, স্ক্রিপ্টিং ভাষাগুলি প্রায়শই সমস্যার দ্রুত সমাধান দেয় তবে সঠিক সমাধান পেতে সঠিক কৌশলগুলি (পড়ুন: অনুকূলিতকরণ) প্রয়োগ করতে হবে।
টাইলার ক্রম্পটন

3

যখন আমি এই উত্তরটি লিখেছি, আমি কেবল <বনাম <= সাধারণভাবে শিরোনাম প্রশ্নটি দেখছিলাম, ধ্রুবক a < 901বনামের নির্দিষ্ট উদাহরণ নয় a <= 900। অনেকগুলি সংকলক সর্বদা <এবং এর মধ্যে রূপান্তর করে ধ্রুবকগুলির <=পরিমাণকে সঙ্কুচিত করে , যেমন x86 তাত্ক্ষণিক অপারেন্ডারে -128..127 এর জন্য 1-বাইটের সংক্ষিপ্ত আকার রয়েছে।

এআরএম এবং বিশেষত এআরচ For৪ এর জন্য, তাত্ক্ষণিকভাবে এনকোড করতে সক্ষম হওয়া কোনও শব্দের কোনও সংকীর্ণ ক্ষেত্রকে কোনও অবস্থানে ঘোরাতে সক্ষম হওয়ার উপর নির্ভর করে। সুতরাং cmp w0, #0x00f000এনকোডেবল cmp w0, #0x00effffহতে পারে , এবং নাও হতে পারে। সুতরাং তুলনা করার জন্য মেক-ইট-ছোট নিয়ম বনাম একটি সংকলন-সময় ধ্রুবক সর্বদা AArch64 এর জন্য প্রযোজ্য নয়।


<বনাম << সাধারণভাবে রানটাইম-পরিবর্তনশীল শর্ত সহ

বেশিরভাগ মেশিনে অ্যাসেম্বলি ভাষায়, তুলনার জন্য একটি তুলনা <=একই ব্যয় হয় <। আপনি এটিতে শাখা করছেন কিনা, 0/1 পূর্ণসংখ্যা তৈরি করতে এটি বুলিয়েইন করে বা ব্রাঞ্চবিহীন সিলেক্ট অপারেশনের (প্র x x সিএমওভের মতো) প্রিডিকেট হিসাবে ব্যবহার করে তা প্রয়োগ করে। অন্যান্য উত্তরগুলি কেবল প্রশ্নের এই অংশটিকেই সম্বোধন করেছে।

তবে এই প্রশ্নটি সি ++ অপারেটরগুলি সম্পর্কে, অপ্টিমাইজারের ইনপুট সাধারণত তারা উভয়ই সমান দক্ষ; বইয়ের পরামর্শগুলি পুরোপুরি বগাস বলে মনে হচ্ছে কারণ সংকলকরা সর্বদা তুলনাকে রূপান্তর করতে পারে যা তারা asm এ প্রয়োগ করে। তবে ব্যবহার করার ক্ষেত্রে অন্তত একটি ব্যতিক্রম রয়েছে<= দুর্ঘটনাক্রমে এমন কিছু তৈরি করতে পারে যা সংকলক অনুকূলিত করতে পারে না।

একটি লুপ শর্ত হিসাবে, মামলা আছে কোথায় আছেন তা <=হল গুণগতভাবে থেকে আলাদা <, যখন এটি প্রতিপাদন করে একটি লুপ অসীম নয় থেকে কম্পাইলার স্টপ। এটি অটো-ভেক্টরাইজেশন অক্ষম করে একটি বড় পার্থক্য আনতে পারে।

স্বাক্ষরযুক্ত ওভারফ্লোটি স্বাক্ষরিত ওভারফ্লো (ইউবি) এর বিপরীতে চারদিকে বেস -২ মোড়ানো হিসাবে ভাল সংজ্ঞায়িত। স্বাক্ষরযুক্ত লুপ কাউন্টারগুলি সাধারণত সংকলকগুলির সাথে এটি থেকে নিরাপদ থাকে যা স্বাক্ষরিত-ওভারফ্লো ইউবি না হওয়ার উপর ভিত্তি করে অনুকূলিত করে: ++i <= sizeসর্বদা মিথ্যা হয়ে যাবে। ( প্রতিটি সি প্রোগ্রামার অপরিশোধিত আচরণ সম্পর্কে কী জেনে রাখা উচিত )

void foo(unsigned size) {
    unsigned upper_bound = size - 1;  // or any calculation that could produce UINT_MAX
    for(unsigned i=0 ; i <= upper_bound ; i++)
        ...

সংকলকগণ কেবলমাত্র অনির্ধারিত আচরণের দিকে পরিচালিত করে, সমস্ত সম্ভাব্য ইনপুট মানগুলির জন্য সি ++ উত্সের (সংজ্ঞায়িত এবং আইনত পর্যবেক্ষণযোগ্য) আচরণ সংরক্ষণের উপায়গুলিতে কেবল অনুকূল করতে পারেন

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

এই ক্ষেত্রে, size=0বাড়ে upper_bound=UINT_MAXএবং i <= UINT_MAXসর্বদা সত্য। সুতরাং এই লুপটি অসীম size=0, এবং সংকলকটিকে সম্মান করতে হবে যদিও আপনি প্রোগ্রামার হিসাবে সম্ভবত কখনও কখনও আকার = 0 পাস করার ইচ্ছা করে না। সংকলক যদি এই ফাংশনটিকে কলারের সাথে ইনলাইন করতে পারে যেখানে এটি প্রমাণ করতে পারে যে আকার = 0 অসম্ভব, তবে দুর্দান্ত, এটি এটি যেমনটি করতে পারে তেমন অনুকূল করতে পারে i < size

লুটের অভ্যন্তরে সত্যিকারের মান প্রয়োজন না হলে এএসএম লাইক if(!size) skip the loop; do{...}while(--size);একটি for( i<size )লুপকে অনুকূলকরণের একটি সাধারণভাবে কার্যকর উপায় i( কেন লুপগুলি সর্বদা "ডু ... যখন" স্টাইল (টেল জাম্প) তে সংকলিত হয়? )।

তবে এটি অসীম হতে পারে না এমন সময়টি করে: যদি প্রবেশ করে তবে size==0আমরা 2 ite n পুনরাবৃত্তি পাই। ( লুপ সি এর জন্য স্বাক্ষরযুক্ত সমস্ত পূর্ণসংখ্যার উপরে আইট্রেট করা শূন্য সহ সমস্ত স্বাক্ষরিত পূর্ণসংখ্যার উপর একটি লুপ প্রকাশ করা সম্ভব করে তোলে, তবে যেমন বহনকারী পতাকাটি এটি asm তে থাকে তেমন সহজ নয়))

লুপের কাউন্টারটি মোছার সম্ভাবনা রয়েছে বলে আধুনিক সংকলকরা প্রায়শই কেবল "হাল ছেড়ে" দেন এবং প্রায় আক্রমণাত্মকভাবে অনুকূলিত হন না।

উদাহরণ: 1 থেকে n পর্যন্ত পূর্ণসংখ্যার যোগফল

স্বাক্ষরবিহীন স্বাক্ষর ব্যবহারের মাধ্যমে i <= nঝাঁকুনির আইডিয়োম-স্বীকৃতি যাsum(1 .. n) গৌসের n * (n+1) / 2সূত্রের ভিত্তিতে বন্ধ ফর্মের সাথে লুপগুলি অনুকূল করে ।

unsigned sum_1_to_n_finite(unsigned n) {
    unsigned total = 0;
    for (unsigned i = 0 ; i < n+1 ; ++i)
        total += i;
    return total;
}

গডবোল্ট সংকলক এক্সপ্লোরারের ক্ল্যাং 7.0 এবং জিসিসি 8.2 থেকে x86-64 এএসএম

 # clang7.0 -O3 closed-form
    cmp     edi, -1       # n passed in EDI: x86-64 System V calling convention
    je      .LBB1_1       # if (n == UINT_MAX) return 0;  // C++ loop runs 0 times
          # else fall through into the closed-form calc
    mov     ecx, edi         # zero-extend n into RCX
    lea     eax, [rdi - 1]   # n-1
    imul    rax, rcx         # n * (n-1)             # 64-bit
    shr     rax              # n * (n-1) / 2
    add     eax, edi         # n + (stuff / 2) = n * (n+1) / 2   # truncated to 32-bit
    ret          # computed without possible overflow of the product before right shifting
.LBB1_1:
    xor     eax, eax
    ret

তবে নিষ্পাপ সংস্করণের জন্য, আমরা কেবল ঝাঁকুনি থেকে একটি বোবা লুপ পাই।

unsigned sum_1_to_n_naive(unsigned n) {
    unsigned total = 0;
    for (unsigned i = 0 ; i<=n ; ++i)
        total += i;
    return total;
}
# clang7.0 -O3
sum_1_to_n(unsigned int):
    xor     ecx, ecx           # i = 0
    xor     eax, eax           # retval = 0
.LBB0_1:                       # do {
    add     eax, ecx             # retval += i
    add     ecx, 1               # ++1
    cmp     ecx, edi
    jbe     .LBB0_1            # } while( i<n );
    ret

জিসিসি কোনওভাবেই ক্লোজড ফর্ম ব্যবহার করে না, সুতরাং লুপ শর্তের পছন্দটি সত্যই এটির ক্ষতি করে না ; এটি iএক্সএমএম রেজিস্টারের উপাদানগুলিতে সমান্তরালে 4 টি মান চালিয়ে সিমডি সংখ্যার সংযোজন সহ স্বয়ংক্রিয়ভাবে ভেক্টরাইজ করে ।

# "naive" inner loop
.L3:
    add     eax, 1       # do {
    paddd   xmm0, xmm1    # vect_total_4.6, vect_vec_iv_.5
    paddd   xmm1, xmm2    # vect_vec_iv_.5, tmp114
    cmp     edx, eax      # bnd.1, ivtmp.14     # bound and induction-variable tmp, I think.
    ja      .L3 #,       # }while( n > i )

 "finite" inner loop
  # before the loop:
  # xmm0 = 0 = totals
  # xmm1 = {0,1,2,3} = i
  # xmm2 = set1_epi32(4)
 .L13:                # do {
    add     eax, 1       # i++
    paddd   xmm0, xmm1    # total[0..3] += i[0..3]
    paddd   xmm1, xmm2    # i[0..3] += 4
    cmp     eax, edx
    jne     .L13      # }while( i != upper_limit );

     then horizontal sum xmm0
     and peeled cleanup for the last n%3 iterations, or something.

এটিতে একটি সরল স্কেলার লুপ রয়েছে যা আমি মনে করি এটি খুব ছোট nএবং / অথবা অসীম লুপের ক্ষেত্রে ব্যবহার করে।

বিটিডাব্লু, এই উভয় লুপ লুপ ওভারহেডে একটি নির্দেশনা (এবং স্যান্ডিব্রিজে-পরিবার সিপিইউগুলিতে একটি উওফ) নষ্ট করে। sub eax,1/ cmp / jcc এর jnzপরিবর্তে add eax,1আরও দক্ষ হবে। 2 এর পরিবর্তে 1 টি ইউওপ (সাব / জিসিসি বা সিএমপি / জিসিসির ম্যাক্রো-ফিউশন পরে)। উভয় লুপের পরে কোড EAX নিঃশর্তভাবে লিখেছে, সুতরাং এটি লুপের কাউন্টারটির চূড়ান্ত মান ব্যবহার করছে না।


চমৎকার অবলম্বন উদাহরণ। EFLAGS ব্যবহারের কারণে অর্ডার কার্যকরকরণের বাইরে যাওয়ার সম্ভাব্য প্রভাব সম্পর্কে আপনার অন্যান্য মন্তব্য সম্পর্কে কী? এটি কি নিখুঁত তাত্ত্বিক বা এটি আসলে ঘটতে পারে যে কোনও জেবি কোনও জেবিইর চেয়ে ভাল পাইপলাইন নিয়ে যায়?
rustyx

@ রুস্টিক্স: আমি কি অন্য কোথাও অন্য উত্তরে মন্তব্য করেছি? সংকলকগণ কোডটি নির্গত করতে যাচ্ছেন যা আংশিক-পতাকা স্টলের কারণ হয়ে থাকে, এবং অবশ্যই কোনও সি <বা এর জন্য নয় <=। তবে নিশ্চিত, test ecx,ecx/ bt eax, 3/ jbeঝাঁপিয়ে পড়বে যদি জেডএফ সেট করা থাকে (ecx == 0), বা সিএফ সেট করা থাকলে (EAX == 1 এর বিট 3), বেশিরভাগ সিপিইউতে আংশিক পতাকা স্টল তৈরি করে কারণ এটি পড়ার পতাকাগুলি সমস্তই নয় কোনও পতাকা লিখতে শেষ নির্দেশনা থেকে আসা। স্যান্ডিব্রিজে পরিবারে এটি আসলে স্টল করে না, কেবল একটি মার্জিং উওপ সন্নিবেশ করা দরকার। cmp/ testসমস্ত পতাকা লিখুন, তবে btজেডএফকে অবিস্মরণযুক্ত ছেড়ে দেয়। felixcloutier.com/x86/bt
পিটার

2

কম্পিউটার তৈরি করা লোকেরা যদি বুলিয়ান যুক্তি দিয়ে খারাপ হয় তবেই। যা তাদের হওয়া উচিত নয়।

প্রতিটি তুলনা (>= <= > < ) একই গতিতে করা যেতে পারে।

প্রতিটি তুলনা কী, এটি কেবল একটি বিয়োগ (পার্থক্য) এবং এটি ইতিবাচক / নেতিবাচক কিনা তা দেখানো।
(যদিmsb সেট করা থাকে তবে সংখ্যাটি নেতিবাচক)

কীভাবে চেক করবেন a >= b? ইতিবাচক a-b >= 0কিনা a-bতা সাব চেক করুন ।
কীভাবে চেক করবেন a <= b? ইতিবাচক 0 <= b-aকিনা b-aতা সাব চেক করুন ।
কীভাবে চেক করবেন a < b? a-b < 0Checkণাত্মক কিনা a-bতা সাব চেক করুন ।
কীভাবে চেক করবেন a > b? সাব 0 > b-aচেক যদিb-a তা ।

সহজ কথায় বলতে গেলে কম্পিউটার কেবল প্রদত্ত অপের জন্য ফণার নীচে এটি করতে পারে:

a >= b== msb(a-b)==0
a <= b== msb(b-a)==0
a > b== msb(b-a)==1
a < b==msb(a-b)==1

এবং অবশ্যই কম্পিউটার আসলে কি প্রয়োজন হত না ==0বা ==1পারেন।
জন্য ==0এটা ঠিক invert পারে msbবর্তনী থেকে।

যাইহোক, তারা অবশ্যই LOL a >= bহিসাবে গণনা করা হত নাa>b || a==b

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