জিসিসি কেন * * * * * * * * * * * * (ট * (এ * এ * এ) * (এ * এ * ক) কে অনুকূলিত করে না?


2119

আমি একটি বৈজ্ঞানিক অ্যাপ্লিকেশন নেভিগেশন কিছু সংখ্যাগত অপ্টিমাইজেশন করছি। একটি জিনিস আমি লক্ষ্য করেছি যে জিসিসি কলটি pow(a,2)সংকলন করে কলটি অনুকূল করে তুলবে a*a, তবে কলটি pow(a,6)অনুকূলিত হয়নি এবং প্রকৃতপক্ষে লাইব্রেরির ফাংশনটি কল করবে pow, যা কার্য সম্পাদনকে অনেক ধীর করে দেয়। (বিপরীতে, ইন্টেল সি ++ কম্পাইলার , এক্সিকিউটেবল icc, লাইব্রেরি কলটি মুছে ফেলবে pow(a,6)))

আমি কি সম্পর্কে জানতে আগ্রহী am যে আমি যখন প্রতিস্থাপিত হয় pow(a,6)সঙ্গে a*a*a*a*a*aজিসিসি 4.5.1 এবং বিকল্প "ব্যবহার -O3 -lm -funroll-loops -msse4", এটি 5 ব্যবহার mulsdনির্দেশাবলী:

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13

যখন আমি লিখি (a*a*a)*(a*a*a), এটি উত্পাদন করে

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13

যা বহুগুণ নির্দেশাবলীর সংখ্যা 3 হ্রাস করে 3 iccএকইরকম আচরণ করে।

সংকলকরা কেন এই অপ্টিমাইজেশনের কৌশলটি স্বীকৃতি দেয় না?


13
"স্বীকৃতি পাওয়ার (a, 6)" এর অর্থ কী?
বরুণ মাদিয়াথ

659
উম ... আপনি কি জানেন যে একটি একটি একটি একটি একটি A এবং (ক একটি ক) * (ক একটি * ক) ফ্লোটিং পয়েন্ট সংখ্যার একই, তাই না না? আপনাকে এর জন্য আপনাকে ফান্সফ্যাক-ম্যাথ বা -ফাস্ট-ম্যাথ বা কিছু ব্যবহার করতে হবে।
দামন

106
আমি আপনাকে ডেভিড গোল্ডবার্গের "ফ্লুটিং পয়েন্ট অ্যারিমেটিক সম্পর্কে প্রতিটি কম্পিউটার বিজ্ঞানীর কী জানা উচিত" পড়ার পরামর্শ দিচ্ছি: download.oracle.com/docs/cd/E19957-01/806-3568/… যার পরে আপনার আরও সম্পূর্ণ বোঝা হবে আপনি সবেমাত্র প্রবেশ করেছেন যে টার পিট!
ফিল আর্মস্ট্রং

189
একটি পুরোপুরি যুক্তিসঙ্গত প্রশ্ন। 20 বছর আগে আমি একই সাধারণ প্রশ্ন জিজ্ঞাসা করেছি, এবং সেই একক বাধাটি পিষে একটি মন্টি কার্লো সিমুলেশন কার্যকর করার সময়টি 21 ঘন্টা থেকে 7 ঘন্টা করে কমিয়েছে। অভ্যন্তরীণ লুপের কোডটি প্রক্রিয়াটিতে 13 ট্রিলিয়ন বার কার্যকর করা হয়েছিল, তবে এটি একটি রাতারাতি উইন্ডোতে সিমুলেশন পেয়েছিল। (নীচের উত্তর দেখুন)

23
(a*a)*(a*a)*(a*a)মিশ্রণটিও ফেলে দিতে পারে । বহু গুণ একই, তবে সম্ভবত আরও নির্ভুল।
রোক ক্রালজ

উত্তর:


2738

কারণ ভাসমান পয়েন্ট ম্যাথটি অ্যাসোসিয়েটিভ নয় । ভাসমান পয়েন্টের গুণকে আপনি অপারেন্টগুলিকে যেভাবে গোষ্ঠীভুক্ত করেন তার উত্তরের সংখ্যাগত নির্ভুলতার উপর প্রভাব ফেলে।

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


10
হ্যাঁ. -ফাস্ট-ম্যাথের সাথে এটি এমন অপটিমাইজেশন করছে। ভাল ধারণা! তবে যেহেতু আমাদের কোডটি গতির চেয়ে আরও যথার্থতার বিষয়ে উদ্বেগ প্রকাশ করেছে, তাই এটি পাস না করাই ভাল।
xis

19
আইআইআরসি সি 99 সংকলককে এই জাতীয় "অনিরাপদ" এফপি অপ্টিমাইজেশানগুলি করার অনুমতি দেয়, তবে জিসিসি (x87 ব্যতীত অন্য কোনও কিছুতে) আইইইই 754 অনুসরণ করার জন্য একটি যুক্তিসঙ্গত প্রচেষ্টা করে - এটি "ত্রুটির সীমা" নয়; শুধুমাত্র একটি সঠিক উত্তর আছে
টিসি।

14
বাস্তবায়নের বিশদটি powএখানে বা সেখানে নেই; এই উত্তর এমনকি রেফারেন্স না pow
স্টিফেন ক্যানন

14
@ আনডআর: আইসিসি পুনরায় সংযোগের অনুমতি দেওয়ার ক্ষেত্রে খেলাপি। আপনি যদি মানসম্মত আচরণের আচরণ পেতে চান তবে আপনার -fp-model preciseআইসিসির সাথে সেট করা দরকার । clangএবং gccকঠোর কনফারেন্স রিট পুনঃস্থাপনের জন্য ডিফল্ট।
স্টিফেন ক্যানন

49
@ এক্সিস, এটি আসলে ভুল নয় -fassociative-mathnot এটা ঠিক a*a*a*a*a*aএবং (a*a*a)*(a*a*a)ভিন্ন। এটি নির্ভুলতার বিষয়ে নয়; এটি স্ট্যান্ডার্ড কনফারেন্স এবং কঠোরভাবে পুনরাবৃত্তিযোগ্য ফলাফলগুলি সম্পর্কে, যেমন কোনও সংকলকতে একই ফলাফল। ভাসমান পয়েন্ট সংখ্যা ইতিমধ্যে সঠিক নয়। এটি সংকলন করা খুব কমই অনুচিত -fassociative-math
পল ড্রাগার

652

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

এটি লিখতে ব্যথা হতে পারে, যদিও; সংকলক কেন আপনি যখন ব্যবহার করছেন ঠিক তখনই [যা আপনি মনে করেন] সঠিক জিনিস করতে পারবেন না pow(a,6)? কারণ এটি করা ভুল কাজ হবে। একটি ভাল গণিত লাইব্রেরি সহ একটি প্ল্যাটফর্মে, pow(a,6)হয় a*a*a*a*a*aবা অন্য তুলনায় উল্লেখযোগ্যভাবে আরও সঠিক (a*a*a)*(a*a*a)। কিছু তথ্য সরবরাহ করার জন্য, আমি আমার ম্যাক প্রোতে একটি ছোট্ট পরীক্ষা চালিয়েছি, [১,২) এর মধ্যে সমস্ত একক-নির্ভুলতা ভাসমান সংখ্যার জন্য ^ 6 মূল্যায়নের মধ্যে সবচেয়ে খারাপ ত্রুটিটি পরিমাপ করেছি:

worst relative error using    powf(a, 6.f): 5.96e-08
worst relative error using (a*a*a)*(a*a*a): 2.94e-07
worst relative error using     a*a*a*a*a*a: 2.58e-07

powএকটি গুণ গাছের পরিবর্তে ব্যবহার করা 4 এর গুণক দ্বারা আবদ্ধ ত্রুটি হ্রাস করে । সংকলকগণ "অপ্টিমাইজেশন" তৈরি করবেন না যা ব্যবহারকারীর (যেমন মাধ্যমে -ffast-math) লাইসেন্স না দিয়ে ত্রুটি বৃদ্ধি করে ।

নোট করুন যে জিসিসি __builtin_powi(x,n)বিকল্প হিসাবে সরবরাহ করে pow( ), যা একটি ইনলাইন গুণক গাছ উত্পন্ন করা উচিত। আপনি যদি পারফরম্যান্সের জন্য নির্ভুলতা বাণিজ্য করতে চান তবে এটি ব্যবহার করুন তবে দ্রুত গণিত সক্ষম করতে চান না।


29
আরও লক্ষ করুন যে ভিজ্যুয়াল সি ++ পাও () এর একটি 'বর্ধিত' সংস্করণ সরবরাহ করে। সাথে কল _set_SSE2_enable(<flag>)করে flag=1, এটি সম্ভব হলে এসএসই 2 ব্যবহার করবে। এটি নির্ভুলতা কিছুটা কমিয়ে দেয় তবে গতি উন্নত করে (কিছু ক্ষেত্রে)। এমএসডিএন: _সেটএসএসই_আবারযোগ্য () এবং পাউ ()
টেকটেক

18
@ টেকটেক: যে কোনও হ্রাসযোগ্য নির্ভুলতা মাইক্রোসফ্টের প্রয়োগের কারণে, ব্যবহৃত রেজিস্টরের আকারের কারণে নয়। লাইব্রেরির লেখক যদি এতটাই অনুপ্রাণিত হন তবে কেবল 32-বিট রেজিস্টার ব্যবহার করে সঠিকভাবে গোল করা সম্ভব pow। এসএসই-ভিত্তিক powবাস্তবায়নগুলি যা বেশিরভাগ x87- ভিত্তিক বাস্তবায়নগুলির চেয়ে বেশি নির্ভুল এবং এমন বাস্তবায়নও রয়েছে যেগুলি গতির জন্য কিছু নির্ভুলতার সাথে ব্যবসা করে।
স্টিফেন ক্যানন

9
@ টেকটেক: অবশ্যই, আমি কেবল স্পষ্ট করে বলতে চেয়েছিলাম যে সঠিকতা হ্রাস লাইব্রেরি লেখকদের পছন্দ অনুসারে হয়েছে, এসএসই ব্যবহারের সাথে অন্তর্নিহিত নয়।
স্টিফেন ক্যানন

7
আপেক্ষিক ত্রুটিগুলি গণনার জন্য আপনি এখানে "সোনার স্ট্যান্ডার্ড" হিসাবে কী ব্যবহার করেছেন তা জানতে আগ্রহী - আমি সাধারণত প্রত্যাশা করতাম যে এটি হবে a*a*a*a*a*a, তবে সম্ভবত এটি তেমনটি নয়! :)
j_random_hacker

8
@j_random_hacker: যেহেতু আমি একটি স্বর্ণমান জন্য সিঙ্গল-স্পষ্টতা ফলাফল, ডবল স্পষ্টতা যথেষ্ট তুলনা করা হয় - একটি থেকে ত্রুটি একটি একটি একটি একটি একটি ডবল মধ্যে নির্ণিত * অতি হয় একক স্পষ্টতা কম্পিউটেশন কোনো ত্রুটি চেয়ে ছোট।
স্টিফেন ক্যানন

168

আরেকটি অনুরূপ ক্ষেত্রে: অধিকাংশ কম্পাইলার হবে না অপ্টিমাইজ a + b + c + dকরার (a + b) + (c + d)হিসেবে দেওয়া (যেমন হিসাবে এবং মূল্যায়নের এটা (এই একটি অপ্টিমাইজেশান যেহেতু দ্বিতীয় অভিব্যক্তি ভাল pipelined করা যেতে পারে) (((a + b) + c) + d))। এটিও কোণার মামলার কারণে:

float a = 1e35, b = 1e-5, c = -1e35, d = 1e-5;
printf("%e %e\n", a + b + c + d, (a + b) + (c + d));

এই ফলাফল 1.000000e-05 0.000000e+00


10
এটি ঠিক এক রকম নয়। গুণফল / বিভাগগুলির ক্রম পরিবর্তন করুন (০ দ্বারা বিভাজন বাদে) যোগফল / বিয়োগের চাংগিন ক্রমের চেয়ে নিরাপদ। আমার বিনীত মতে, সংকলকটি মাল্টস / ডিভগুলি সংযুক্ত করার চেষ্টা করা উচিত। কারণ এটি করা অপারেশনগুলির মোট সংখ্যা হ্রাস করে এবং পারফরম্যান্স লাভের পাশেও একটি নির্ভুল লাভ।
কফডি ডেভেলপার

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

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

8
@ ডারিওইউ: মুল / ডিভির সাথে ঝুঁকি আলাদা: পুনঃক্রম করা হয় চূড়ান্ত ফলাফলের ক্ষেত্রে একটি নগণ্য পরিবর্তন করে, অথবা এক্সটেনশনটি কোনও পর্যায়ে উপচে পড়ে যায় (যেখানে এটি আগে ছিল না) এবং ফলাফলটি ব্যাপকভাবে পৃথক হয় (সম্ভাব্যভাবে + ইনফ এবং 0)।
পিটার কর্ডেস

@ গেইম ডেভেলপার অপ্রত্যাশিত উপায়ে একটি নির্ভুল লাভ চাপিয়ে দেওয়া অত্যন্ত সমস্যাযুক্ত।
কৌতূহলী

80

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

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

template<unsigned N> struct power_impl;

template<unsigned N> struct power_impl {
    template<typename T>
    static T calc(const T &x) {
        if (N%2 == 0)
            return power_impl<N/2>::calc(x*x);
        else if (N%3 == 0)
            return power_impl<N/3>::calc(x*x*x);
        return power_impl<N-1>::calc(x)*x;
    }
};

template<> struct power_impl<0> {
    template<typename T>
    static T calc(const T &) { return 1; }
};

template<unsigned N, typename T>
inline T power(const T &x) {
    return power_impl<N>::calc(x);
}

কৌতুহলের জন্য স্পষ্টতা: এটি শক্তির গণনা করার সর্বোত্তম উপায়টি খুঁজে পায় না, তবে যেহেতু সর্বোত্তম সমাধানটি অনুসন্ধান করা একটি এনপি-সম্পূর্ণ সমস্যা এবং এটি ক্ষুদ্র ক্ষমতার পক্ষে যাই হোক না কেন (ব্যবহারের বিপরীতে pow), হট্টগোল করার কোনও কারণ নেই বিস্তারিত সহ।

তারপরে এটি হিসাবে ব্যবহার করুন power<6>(a)

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

আপনি সম্ভবত এটিও ভুলে যেতে পারেন যে এটি সি ++ এবং কেবল এটি সি প্রোগ্রামে ব্যবহার করুন (যদি এটি সি ++ সংকলক সহ সংকলন করে)।

আশা করি এটি কার্যকর হতে পারে।

সম্পাদনা করুন:

আমার সংকলক থেকে এটিই আমি পেয়েছি:

জন্য a*a*a*a*a*a,

    movapd  %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm1, %xmm0

জন্য (a*a*a)*(a*a*a),

    movapd  %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm0, %xmm0

জন্য power<6>(a),

    mulsd   %xmm0, %xmm0
    movapd  %xmm0, %xmm1
    mulsd   %xmm0, %xmm1
    mulsd   %xmm0, %xmm1

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

7
আধুনিক প্রসেসরগুলিতে, গতি বিলম্বের দ্বারা সীমাবদ্ধ। উদাহরণস্বরূপ, একটি গুণটির ফলাফল পাঁচটি চক্রের পরে উপলব্ধ হতে পারে। এই পরিস্থিতিতে, কিছু শক্তি তৈরির দ্রুততম উপায় সন্ধান করা আরও জটিল।
gnasher729

3
আপনি পাওয়ার ট্রিটি চেষ্টা করতে পারেন যা আপেক্ষিক বৃত্তাকার ত্রুটির জন্য নিম্নতম উপরের বাউন্ডকে দেয় বা সর্বনিম্ন গড় আপেক্ষিক বৃত্তাকার ত্রুটি দেয়।
gnasher729

1
বুস্টেরও এর জন্য সমর্থন রয়েছে, যেমন বুস্ট :: গণিত :: পা <<> (এন); আমি মনে করি এটি এমনকি সাধারণ কারণগুলি বের করে গুণনের সংখ্যা হ্রাস করার চেষ্টা করে।
gast128

নোট করুন যে শেষটি সমান (একটি ** 2) ** 3
মিনম্যাকস্যাভগ

62

যখন কোনও পূর্ণসংখ্যা a*a*a*a*a*aহয় (a*a*a)*(a*a*a)তখন জিসিসি প্রকৃতপক্ষে অনুকূলিত হয় । আমি এই আদেশ দিয়ে চেষ্টা করেছি:

$ echo 'int f(int x) { return x*x*x*x*x*x; }' | gcc -o - -O2 -S -masm=intel -x c -

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

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

; x is in edi to begin with.  eax will be used as a temporary register.
mov  eax, edi  ; temp = x
imul eax, edi  ; temp = x * temp
imul eax, edi  ; temp = x * temp
imul eax, eax  ; temp = temp * temp

আমি লিনাক্স টাকশাল 16 পেট্রা, একটি উবুন্টু ডেরিভেটিভ সিস্টেম জিসিসি ব্যবহার করছি। এখানে জিসিসির সংস্করণটি রয়েছে:

$ gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1

যেমন অন্যান্য পোস্টার নোট করেছেন, এই বিকল্পটি ভাসমান পয়েন্টে সম্ভব নয়, কারণ ভাসমান পয়েন্ট গণিতটি সাহিত্যের নয়।


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

51

কারণ একটি 32-বিট ভাসমান-পয়েন্ট নম্বর - যেমন 1.024 - 1.024 নয়। কম্পিউটারে, 1.024 হ'ল একটি বিরতি: (1.024-ই) থেকে (1.024 + ই), যেখানে "ই" একটি ত্রুটি উপস্থাপন করে। কিছু লোক এটি অনুধাবন করতে ব্যর্থ হয় এবং এও বিশ্বাস করে যে * একটি * এর মধ্যে এই সংখ্যার সাথে কোনও ত্রুটি যুক্ত না করে স্বেচ্ছাচারিতা-নির্ভুলতা সংখ্যার গুণন করা। কিছু লোক এটি বুঝতে ব্যর্থ হওয়ার কারণ সম্ভবত তারা প্রাথমিক বিদ্যালয়গুলিতে গণিতের গণনা ব্যবহার করেছিল: ত্রুটিযুক্ত সংযুক্তি ছাড়াই কেবল আদর্শ সংখ্যার সাথে কাজ করা, এবং বিশ্বাস করে যে গুণটি করার সময় কেবল "ই" উপেক্ষা করা ঠিক হবে OK তারা "ফ্লোট এ = 1.2", "এ * এ * এ" এবং অনুরূপ সি কোডগুলিতে "ই" অন্তর্নিহিত দেখতে পাবে না।

যদি প্রোগ্রামারদের সংখ্যাগরিষ্ঠরা সি-এক্সপ্রেশন একটি * আ * আ * আ * ক * আসলে আদর্শ সংখ্যার সাথে কাজ করে না এমন ধারণাটি স্বীকার করে (এবং কার্যকর করতে সক্ষম হয়), তখন জিসিসি সংকলকটি "এ * এটিকে অপ্টিমাইজ করার জন্য বিনামূল্যে হবে" * a * a * a * a "to" t = (a * a); t * t * t "এর জন্য একটি ছোট সংখ্যার গুণক প্রয়োজন। তবে দুর্ভাগ্যক্রমে, জিসিসি সংকলক জানে না যে কোডার লেখার প্রোগ্রামার মনে করে যে "এ" একটি ত্রুটিযুক্ত বা ছাড়া একটি সংখ্যা। এবং তাই জিসিসি কেবলমাত্র সোর্স কোডের মত দেখতে যা করবে - কারণ এটিই জিসিসি তার "নগ্ন চোখে" দেখে।

... একবার আপনি কি জানেন প্রোগ্রামার ধরনের আপনি হয়, আপনি "-ffast-গণিত" সুইচ ব্যবহার করতে পারেন জিসিসি বলতে যে, "আরে, জিসিসি, আমি জানি আমি যা করছি তা!"। এটি জিসিসিকে একটি * a * a * a * a * a কে একটি আলাদা টেক্সটের টুকরোতে রূপান্তর করতে অনুমতি দেবে - এটি একটি * a * a * a * a * a থেকে আলাদা দেখায় - তবু ত্রুটির ব্যবধানের মধ্যে একটি সংখ্যাকে গণনা করে একটি * একটি * একটি * একটি * একটি * ক। এটি ঠিক আছে, আপনি ইতিমধ্যে জানেন যে আপনি বিরতি নিয়ে কাজ করছেন, আদর্শ সংখ্যা নয়।


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

3
@ ডোনালফেলোস: আইইইই স্ট্যান্ডার্ডের প্রয়োজন যে ফ্লোটিং-পয়েন্ট গণনা ফলাফলটি উত্সাহ দেয় যা উত্স অপারেন্ডস যথাযথ মান হলে ফলাফলটি সবচেয়ে সঠিকভাবে মেলে তবে এর অর্থ এই নয় যে তারা আসলে সঠিক মানগুলি উপস্থাপন করে exact 0.1f (1,677,722 +/- 0.5) / 16,777,216 হিসাবে বিবেচনা করা এটি অনেক ক্ষেত্রে আরও সহায়ক, যা সঠিক পরিমাণ হিসাবে বিবেচনা করার চেয়ে সেই অনিশ্চয়তার দ্বারা আরোপিত দশমিক সংখ্যাগুলির সাথে প্রদর্শিত হওয়া উচিত (1,677,722 +/- 0.5) / 16,777,216 (যা 24 দশমিক অঙ্কে প্রদর্শিত হবে)।
সুপারক্যাট

23
@supercat: আইইইই-754 পয়েন্ট যে ফ্লোটিং পয়েন্ট ডেটার উপর প্রশংসনীয় স্পষ্ট না সঠিক মান প্রতিনিধিত্ব; ৩.২ - ৩.৪ ধারাটি প্রাসঙ্গিক বিভাগ। আপনি অবশ্যই অন্যথায় তাদের ব্যাখ্যা করতে বেছে নিতে পারেন, যেমন আপনি 3 +/- 0.5 এর int x = 3অর্থ হিসাবে ব্যাখ্যা করতে বেছে নিতে পারেন x
স্টিফেন ক্যানন

7
@ সুপের্যাট: আমি সম্পূর্ণরূপে একমত, তবে এর অর্থ এই নয় যে Distanceএটির সংখ্যাসূচক মানের সাথে সমান নয়; এর অর্থ হ'ল সংখ্যাসূচক মানটি কিছু শারীরিক পরিমাণের মডেলিংয়ের একমাত্র অনুমান।
স্টিফেন ক্যানন

10
সংখ্যার বিশ্লেষণের জন্য, আপনার মস্তিষ্ক আপনাকে ধন্যবাদ জানাবে যদি আপনি ভাসমান পয়েন্ট সংখ্যাগুলি অন্তর্বর্তী হিসাবে না, তবে যথাযথ মান হিসাবে (যা আপনি যে মানগুলি চেয়েছিলেন ঠিক তেমন হয় না) হিসাবে ব্যাখ্যা করেন। উদাহরণস্বরূপ, যদি x 0.1 এর চেয়ে কম ত্রুটিযুক্ত কোথাও 4.5 গোল হয়, এবং আপনি গণনা (x + 1) - x, "বিরতি" ব্যাখ্যা আপনাকে 0.8 থেকে 1.2 এর ব্যবধানে ছেড়ে যায়, যখন "সঠিক মান" ব্যাখ্যাটি বলে আপনার ফলাফলটি ডাবল নির্ভুলতায় সর্বাধিক 2 ^ (- 50) এর ত্রুটির সাথে 1 হবে।
gnasher729

34

কোনও পোস্টার এখনও ভাসমান এক্সপ্রেশনগুলির সংকোচনের কথা উল্লেখ করেনি (আইএসও সি স্ট্যান্ডার্ড, 6.5 পি 8 এবং 7.12.2)। তাহলে FP_CONTRACTpragma সেট করা হয় ON, কম্পাইলার যেমন একটি অভিব্যক্তি বিবেচনা অনুমোদিত হয় a*a*a*a*a*a, একটি একক অপারেশন হিসাবে হিসাবে যদি একটি একক রাউন্ডইং সঙ্গে ঠিক মূল্যায়ন করেন। উদাহরণস্বরূপ, একটি সংকলক এটি অভ্যন্তরীণ শক্তি ফাংশন দ্বারা প্রতিস্থাপন করতে পারে যা উভয়ই দ্রুত এবং আরও নির্ভুল। এটি বিশেষত আকর্ষণীয় কারণ আচরণটি আংশিকভাবে সরাসরি উত্স কোডে প্রোগ্রামার দ্বারা নিয়ন্ত্রিত হয়, যখন শেষ ব্যবহারকারী দ্বারা সরবরাহিত সংকলক বিকল্পগুলি কখনও কখনও ভুলভাবে ব্যবহার করা যেতে পারে।

FP_CONTRACTপ্রগমার ডিফল্ট অবস্থাটি বাস্তবায়ন-সংজ্ঞায়িত হয়, যাতে কোনও সংকলককে ডিফল্টরূপে এ জাতীয় অনুকূলকরণের অনুমতি দেওয়া হয় allowed সুতরাং পোর্টেবল কোড যা আইইইই 754 নিয়ম কঠোরভাবে অনুসরণ করা প্রয়োজন তা এটিকে স্পষ্টভাবে সেট করা উচিত OFF

যদি কোনও সংকলক এই প্রগমা সমর্থন করে না, তবে বিকাশকারী সেট করতে বেছে নিয়েছে এমন ক্ষেত্রে এটির কোনও অপ্টিমাইজেশন এড়িয়ে রক্ষণশীল হতে হবে OFF

জিসিসি এই প্রগমা সমর্থন করে না, তবে ডিফল্ট বিকল্পগুলির সাথে এটি এটি ধরে নেয় ON; এইভাবে একটি হার্ডওয়্যার এফএমএর সাথে লক্ষ্যবস্তুগুলির জন্য, যদি কেউ এফএমএ a*b+c(এ, বি, সি) রুপান্তর রোধ করতে চায় , তার জন্য একটি বিকল্প সরবরাহ করা প্রয়োজন -ffp-contract=off( যেমন প্রগায়ে স্পষ্টভাবে সেট করা OFF) বা -std=c99(জিসিসিকে কিছুটা মানিয়ে নিতে বলে ) সি স্ট্যান্ডার্ড সংস্করণ, এখানে সি 99, এইভাবে উপরের অনুচ্ছেদটি অনুসরণ করুন)। অতীতে, পরবর্তী বিকল্পটি রূপান্তরটি আটকাচ্ছে না, এর অর্থ হ'ল জিসি এই পয়েন্টটি মানছে না: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37845


3
দীর্ঘকালীন জনপ্রিয় প্রশ্নগুলি কখনও কখনও তাদের বয়স দেখায়। এই প্রশ্নটি ২০১১ সালে জিজ্ঞাসা করা হয়েছিল এবং উত্তর দেওয়া হয়েছিল, যখন জিসিসি তখনকার সাম্প্রতিক সি 99 মানকে যথাযথভাবে সম্মান না করার জন্য ক্ষমা হতে পারে। অবশ্যই এখন এটি 2014, তাই জিসিসি… আহেমে।
পাস্কেল কুয়াক

পরিবর্তে কোনও গ্রহণযোগ্য উত্তর না দিয়ে আপনার তুলনামূলক সাম্প্রতিক ভাসমান-পয়েন্ট প্রশ্নের উত্তর দেওয়া উচিত নয়? কাশি stackoverflow.com/questions/23703408 কাশি
পাসকাল Cuoq

আমি এটি খুঁজে পেয়েছি ... বিড়বিড় করে যে সিসি C99 ভাসমান-পয়েন্ট প্রাগমাস প্রয়োগ করে না।
ডেভিড Monniaux

1
@ ডেভিডমনিয়াক্স প্রাগমাস সংজ্ঞাটি প্রয়োগের জন্য optionচ্ছিক।
টিম সেগুইন

2
@ টিমসেইগাইন তবে যদি প্রগমা প্রয়োগ না করা হয় তবে এর ডিফল্ট মানটি প্রয়োগের জন্য সবচেয়ে সীমাবদ্ধ হওয়া দরকার। আমি মনে করি ডেভিড সে বিষয়েই ভাবছিলেন। জিসিসির সাথে, এখন এটি FP_CONTRACT এর জন্য ঠিক করা হয়েছে যদি কেউ আইএসও সি মোড ব্যবহার করে : এটি প্রগমাটি এখনও প্রয়োগ করে না, তবে আইএসও সি মোডে, এখন ধরে নেওয়া হয় যে প্রগমাটি বন্ধ রয়েছে।
ভিঙ্ক 17

28

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


3
@ গ্রেগগো না, এটি তখনও নির্মাতারা। শব্দের কোনও অর্থে কোনও এলোমেলোতা যুক্ত করা হয়নি।
অ্যালিস

9
@ অ্যালিস এটি মোটামুটি পরিষ্কার বলে মনে হচ্ছে যে এখানে ভিন্ন ভিন্ন প্ল্যাটফর্ম এবং বিভিন্ন সংকলক সংস্করণ ইত্যাদিতে (বাহ্যিক ভেরিয়েবলগুলি যা প্রোগ্রামারের নিয়ন্ত্রণের বাইরে হতে পারে) একই ফলাফল প্রদান করে কোডটির অর্থে 'ডিটারনিস্টিক' ব্যবহার করছে - অভাবের বিপরীতে রান সময় আসল সংখ্যার এলোমেলোতার। আপনি যদি এটি নির্দেশ করে থাকেন যে এটি শব্দের যথাযথ ব্যবহার নয় তবে আমি তার সাথে তর্ক করব না।
গ্রেগগো

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

8
@ অ্যালিসিট আপনি শব্দার্থবিজ্ঞান যুক্তি দিয়ে নিজের নিজের সহ প্রত্যেকের সময় নষ্ট করছেন। তার অর্থ পরিষ্কার ছিল।
লানারু

11
@ লানারু মানদণ্ডের পুরো বিষয়টি শব্দার্থবিজ্ঞান; তার অর্থ স্থিরভাবে পরিষ্কার ছিল না।
এলিস

28

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

মৌলিকভাবে নিম্নলিখিত অপারেশন:

pow(x,y);

কোনও একক গুণ বা বিভাগে ত্রুটি হিসাবে প্রায় একই পরিমাণের একটি সহজাত ত্রুটি রয়েছে ।

নিম্নলিখিত অপারেশন চলাকালীন:

float a=someValue;
float b=a*a*a*a*a*a;

এর মধ্যে একটি সহজাত ত্রুটি রয়েছে যা এর চেয়ে বেশি একটি একক গুণ বা বিভাগের ত্রুটির 5 গুণ (কারণ আপনি 5 টি গুণকে একত্রিত করছেন)।

সংকলকটি যে ধরণের অপ্টিমাইজেশন করছে সে সম্পর্কে সত্যই যত্নবান হওয়া উচিত:

  1. নিখুঁত যদি pow(a,6)করতে a*a*a*a*a*aএটা কার্যকারিতা উন্নত করতে পারে তবে ভাসমান পয়েন্ট সংখ্যার জন্য নির্ভুলতা হ্রাস করতে পারে।
  2. যদি অনুকূলিত হয় a*a*a*a*a*a করার জন্য pow(a,6)এটি আসলে যথার্থতা হ্রাস পায় কারণ "একটি" বিশেষ কিছু মান যে ত্রুটি (2 এর একটি ক্ষমতা বা কিছু ছোট পূর্ণসংখ্যা সংখ্যা) ছাড়া গুণ পারবেন ছিল
  3. অপেক্ষাকৃত তুলনায় নির্ভুলতার ক্ষতি হতে pow(a,6)পারে (a*a*a)*(a*a*a)বা (a*a)*(a*a)*(a*a)এখনও অপ্টিমাইজ করা হলেpow কার্যকারিতার ।

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

অপ্টিমাইজ করার একমাত্র জিনিসটি (ব্যক্তিগত মতামত এবং স্পষ্টতই কোনও নির্দিষ্ট অপ্টিমাইজেশন বা সংকলক পতাকার জিসিসিতে একটি পছন্দ) অপসারণের জন্য "পাও (ক, ২)" এর পরিবর্তে "এ * এ" স্থাপন করা উচিত। কোনও সংকলক বিক্রেতার উচিত সেই একমাত্র বুদ্ধিমান কাজ।


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

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

আপনার উত্তরের দ্বিতীয়ার্ধ পুরোপুরি বিন্দুটি মিস করে যে সংকলকরা কোড উত্পন্ন করার কথা বলে যা উত্স কোড যা বলে, সময়কাল তা কার্যকর করে। এছাড়াও আপনি "নির্ভুলতা" শব্দটি ব্যবহার করেন যখন আপনি "নির্ভুলতা" বোঝান।
পাস্কেল কুয়াক

আপনার
ইনপুটটির

27

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

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

আপনি এখানে যেমন করেছেন তেমন সংকলককে ইঙ্গিত দেওয়ার ক্ষেত্রে কোনও অসুবিধা নেই। তারা কী পার্থক্য আনবে তা দেখার জন্য বিবৃতি এবং অভিব্যক্তিগুলিকে পুনর্বিন্যাস করা মাইক্রো-অপ্টিমাইজেশান প্রক্রিয়ার একটি স্বাভাবিক এবং প্রত্যাশিত অংশ।

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


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

21

এই প্রশ্নের ইতিমধ্যে কয়েকটি ভাল উত্তর রয়েছে, তবে সম্পূর্ণতার জন্য আমি উল্লেখ করতে চেয়েছিলাম যে সি স্ট্যান্ডার্ডের প্রযোজ্য বিভাগটি 5.1.2.2.3 / 15 (যা বিভাগের 1.9 / 9 এর সমান সি ++ 11 মান)। এই বিভাগে বলা হয়েছে যে অপারেটররা কেবল সত্যই যদি সংঘবদ্ধ বা পরিবর্তিত হয় তবেই তারা পুনরায় সংগঠিত হতে পারে।


12

ভাসমান-পয়েন্ট সংখ্যাগুলির জন্যও, জিসিসি প্রকৃতপক্ষে এই অপ্টিমাইজেশনটি করতে পারে। উদাহরণ স্বরূপ,

double foo(double a) {
  return a*a*a*a*a*a;
}

হয়ে

foo(double):
    mulsd   %xmm0, %xmm0
    movapd  %xmm0, %xmm1
    mulsd   %xmm0, %xmm1
    mulsd   %xmm1, %xmm0
    ret

সঙ্গে -O -funsafe-math-optimizations। এই পুনঃক্রমটি আইইইই -754 লঙ্ঘন করে, যদিও এটির জন্য পতাকাটি প্রয়োজন।

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

foo(long):
    movq    %rdi, %rax
    imulq   %rdi, %rax
    imulq   %rdi, %rax
    imulq   %rax, %rax
    ret

শুধু সঙ্গে -O। স্বাক্ষরবিহীন পূর্ণসংখ্যার জন্য, এটি আরও সহজ যেহেতু তারা 2 টির মোড পাওয়ার কাজ করে এবং তাই ওভারফ্লোয়ের পরেও অবাধে পুনঃনির্ধারণ করা যায়।


1
গডবোল্ট লিঙ্কটি ডাবল, ইনট এবং স্বাক্ষরবিহীন। জিসিসি এবং ঝনঝন উভয়ই তিনটি একই উপায়ে (সাথে -ffast-math) অনুকূল করে
পিটার কর্ডেস

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