কেন ঝাঁকুনি x * 1.0 অপসারণ করে তবে x + 0.0 নয়?


125

কেন ক্ল্যাং এই কোডের লুপটি অপ্টিমাইজ করে

#include <time.h>
#include <stdio.h>

static size_t const N = 1 << 27;
static double arr[N] = { /* initialize to zero */ };

int main()
{
    clock_t const start = clock();
    for (int i = 0; i < N; ++i) { arr[i] *= 1.0; }
    printf("%u ms\n", (unsigned)(clock() - start) * 1000 / CLOCKS_PER_SEC);
}

কিন্তু এই কোড লুপ না?

#include <time.h>
#include <stdio.h>

static size_t const N = 1 << 27;
static double arr[N] = { /* initialize to zero */ };

int main()
{
    clock_t const start = clock();
    for (int i = 0; i < N; ++i) { arr[i] += 0.0; }
    printf("%u ms\n", (unsigned)(clock() - start) * 1000 / CLOCKS_PER_SEC);
}

(উভয় সি এবং সি ++ হিসাবে ট্যাগ করা কারণ আমি জানতে চাই যে উত্তরগুলির জন্য পৃথক পৃথক কিনা))


2
বর্তমানে কোনটি অপ্টিমাইজেশন পতাকা সক্রিয় রয়েছে?
Iwillnotexist আইডোনোটেক্সবাদ

1
@ আইলিনোটেক্সিস্ট আইডোনোটেক্সিস্ট: আমি সবেমাত্র ব্যবহার করেছি -O3, কীভাবে এটি সক্রিয় হয় তা কীভাবে চেক করতে হয় তা আমি জানি না।
ব্যবহারকারী541686

2
আপনি কমান্ড লাইনে -স্টাস্ট-ম্যাথ যুক্ত করলে কী হয় তা দেখতে আকর্ষণীয় হবে।
প্লাগওয়াশ

static double arr[N]সি তে অনুমোদিত নয়; constভেরিয়েবলগুলি সেই ভাষায় ধ্রুবক প্রকাশ হিসাবে গণ্য হয় না
এমএম

1
[আপনি ইতিমধ্যে এটি কল করেও সি কীভাবে সি নয় এটি সম্পর্কে স্পষ্ট মন্তব্য
arkোকান

উত্তর:


164

আইইইই 754-2008 ফ্লোটিং-পয়েন্ট অ্যারিমেটিকের জন্য স্ট্যান্ডার্ড এবং আইএসও / আইইসি 10967 ল্যাংগুয়েজ ইন্ডিপেন্ডেন্ট এরিথমেটিক (এলআইএ) স্ট্যান্ডার্ড, পর্ব 1 উত্তর কেন এটি এমন।

আইইইই 754 § 6.3 সাইন বিট

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

যখন ইনপুট বা ফলাফল উভয়ই এনএএন নয়, তখন কোনও পণ্য বা ভাগফলের চিহ্নটি অপারেটরদের লক্ষণের একচেটিয়া OR হয়; যোগফলের চিহ্ন, বা একটি পার্থক্যের চিহ্ন - y কে যোগফল হিসাবে গণনা করা হয় x + ()y), সংযোজনের লক্ষণগুলির মধ্যে একটির থেকে পৃথক; এবং রূপান্তরগুলির ফলাফল, কোয়ান্টাইজ অপারেশন, রাউন্ডটো-ইন্টিগ্রাল অপারেশনস এবং রাউন্ডটোইন্টেগ্রাল্যাক্স্যাক্ট (দেখুন 5.3.1) প্রথম বা একমাত্র অপারেন্ডের চিহ্ন। অপারেটস বা ফলাফল শূন্য বা অসীম হলেও এই নিয়মগুলি প্রযোজ্য।

বিপরীত চিহ্ন সহ দুটি অপারেন্ডের যোগফল (বা দুটি চিহ্নের মতো চিহ্নের পার্থক্য) হ'ল শূন্য হলে, সেই যোগফল (বা পার্থক্য) এর চিহ্নটি রাউন্ডওয়ার্ডনেজিটিভ ব্যতীত সমস্ত বৃত্তাকার-দিক বৈশিষ্ট্যগুলিতে +0 হবে; এই বৈশিষ্ট্যের অধীনে, একটি সঠিক শূন্য রাশি (বা পার্থক্য) এর চিহ্ন −0 হবে। তবে, x + x = x - (−x) x শূন্য হলেও এমনকি এক্স হিসাবে একই চিহ্নটি ধরে রাখে।

সংযোজন এর কেস

ডিফল্ট রাউন্ডিং মোডের অধীনে (রাউন্ড-টু-নিকটবর্তী, টাইস-টু-ইনিও) , আমরা দেখি যে এটি x+0.0উত্পাদন করে x, যখন থাকে xতবে -0.0: আমাদের ক্ষেত্রে দুটি সংখ্যার বিপরীত চিহ্ন রয়েছে যার সমষ্টি শূন্য, এবং §6.3 অনুচ্ছেদ রয়েছে 3 নিয়ম এই সংযোজন উত্পাদন করে+0.0

যেহেতু মূলটির সাথে বিটওয়াইজ অভিন্ন +0.0নয় , এবং এটি একটি বৈধ মান যা ইনপুট হিসাবে ঘটতে পারে, তাই সংকলকটি কোডটি রাখতে বাধ্য হয় যা সম্ভাব্য নেতিবাচক শূন্যগুলিকে রূপান্তর করবে ।-0.0-0.0+0.0

সংক্ষিপ্তসার: ডিফল্ট রাউন্ডিং মোডের অধীনে x+0.0, যদি, হয়x

  • নয় -0.0 , তারপর xনিজেই একটি গ্রহণযোগ্য আউটপুট মান।
  • হয় -0.0 , তারপরে আউটপুট মানটি অবশ্যই হতে হবে +0.0 , যা বিটওয়াসার সাথে একরকম নয় -0.0

গুণটির কেস

ডিফল্ট রাউন্ডিং মোডের অধীনে , এর সাথে কোনও সমস্যা হয় না x*1.0। যদি x:

  • সর্বদা একটি (উপ) সাধারণ সংখ্যা x*1.0 == x
  • হয় +/- infinity, তবে ফলাফলটি +/- infinityএকই চিহ্নের হয়।
  • হয় NaN, তারপর অনুযায়ী

    আইইইই 754 § 6.2.3 NaN প্রচার

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

    যার মানে সূচক এবং অংশক (যদিও চিহ্ন) এর NaN*1.0হয় সুপারিশ ইনপুট থেকে অপরিবর্তিত হতে NaN। উপরের .36.3p1 অনুসারে সাইনটি অনির্ধারিত, তবে একটি বাস্তবায়ন এটি উত্সের সাথে অভিন্ন হিসাবে নির্দিষ্ট করতে পারে NaN

  • এর +/- 0.0পরে, ফলাফলটি 0এর সাইন বিট সহ X6.3p2 এর সাথে 1.0চুক্তিতে সাইন বিটের সাথে XORed হয়। যেহেতু সাইন বিট, 1.0তাই 0ইনপুট থেকে আউটপুট মান অপরিবর্তিত ged সুতরাং, x*1.0 == xএমনকি যখন xএকটি (নেতিবাচক) শূন্য হয়।

বিয়োগের কেস

ডিফল্ট rounding মোড অধীনে , বিয়োগ x-0.0একটি নো-অপ, কারণ এটি সমতূল্য হয় x + (-0.0)। যদি xহয়

  • হয় NaNতারপর §6.3p1 এবং §6.2.3 উপরন্তু এবং গুণ হিসাবে একই ভাবে প্রযোজ্য।
  • হয় +/- infinity, তবে ফলাফলটি +/- infinityএকই চিহ্নের হয়।
  • সর্বদা একটি (উপ) সাধারণ সংখ্যা x-0.0 == x
  • হয় -0.0, তাহলে §.3.৩p2 দ্বারা আমাদের " [...] একটি যোগফলের চিহ্ন বা কোনও পার্থক্যের চিহ্ন - y এর যোগফলকে x + ()y) হিসাবে বিবেচনা করা হয়, সংযোজনের চিহ্নগুলির মধ্যে একটির থেকে পৃথক; "। এই বাহিনী আমাদের দায়িত্ব অর্পণ করা -0.0এর ফলে (-0.0) + (-0.0), কারণ -0.0থেকে সাইন ইন পৃথক কেউ addends এর, যখন +0.0থেকে সাইন ইন পৃথক দুই addends, এই দফা লঙ্ঘন।
  • হ'ল +0.0, তাহলে এটি কেস অফ অ্যাডিশনে(+0.0) + (-0.0) উপরে বিবেচিত সংযোজন ক্ষেত্রে হ্রাস পাবে , যা §§.৩.৩২ দ্বারা দেওয়ার রায় দেওয়া হয়েছে ।+0.0

যেহেতু সমস্ত ক্ষেত্রে ইনপুট মান আউটপুট হিসাবে বৈধ, তাই x-0.0কোনও অপ-বিকল্প এবং x == x-0.0টাউটোলজি বিবেচনা করা অনুমোদিত।

মান-পরিবর্তন অপ্টিমাইজেশান

আইইইই 754-2008 স্ট্যান্ডার্ডের নিম্নলিখিত আকর্ষণীয় উক্তি রয়েছে:

আইইইই 754 § 10.4 শাব্দিক অর্থ এবং মান পরিবর্তনের অপ্টিমাইজেশন

[...]

নিম্নলিখিত মান পরিবর্তনকারী রূপান্তরগুলি, অন্যদের মধ্যে, উত্স কোডের আক্ষরিক অর্থ সংরক্ষণ করে:

  • X শূন্য নয় এবং সিগন্যালিং এনএএন নয় এবং সনাক্তকরণের বৈশিষ্ট্য 0 + x প্রয়োগ করা হলে এক্স এর সমান এক্সপোনেন্ট থাকে।
  • X যখন সিগন্যালিং এনএন নয় এবং পরিচয়ের বৈশিষ্ট্যটি 1 × x প্রয়োগ করা হয় তখন এক্স এর সমান এক্সপোনেন্ট থাকে।
  • শান্ত NaN এর পেডলোড বা সাইন বিট পরিবর্তন করা।
  • [...]

যেহেতু সমস্ত এনএএন এবং সমস্ত অসম্পূর্ণতা একই ঘাতক হিসাবে ভাগ করে, এবং সীমাবদ্ধতার জন্য x+0.0এবং সঠিকভাবে বৃত্তাকার ফলাফলের ঠিক একই মাত্রা থাকে , তাই তাদের প্রকাশক একই।x*1.0xx

sNaNs

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

যাইহোক, ব্যবহারকারী 2357112 মন্তব্যে উল্লেখ করেছেন , সি 11 স্ট্যান্ডার্ড স্পষ্টতই সংকেত NaNs ( sNaN) এর আচরণের অপরিজ্ঞাতভাবে ছেড়ে দেয় , সুতরাং সংকলকটি অনুমান করতে পারে যে সেগুলি ঘটে না, এবং এইভাবে তারা উত্থাপিত ব্যতিক্রমগুলিও ঘটে না। সি ++ 11 স্ট্যান্ডার্ড NaN- কে সিগন্যাল করার আচরণের বর্ণনা বর্ণনা বাদ দেয় এবং এটি এটিকে অপরিবর্তিত রাখে।

রাউন্ডিং মোডগুলি

বিকল্প রাউন্ডিং মোডে, অনুমতিযোগ্য অপ্টিমাইজেশন পরিবর্তন হতে পারে। উদাহরণস্বরূপ, রাউন্ড টু নেগেটিভ-ইনফিনিটি মোডের অধীনে, অপ্টিমাইজেশন x+0.0 -> xজায়েজ x-0.0 -> xহয়ে যায় তবে তা নিষিদ্ধ হয়ে যায়।

জিসিসিকে ডিফল্ট রাউন্ডিং মোড এবং আচরণগুলি ধরে নেওয়া থেকে বিরত রাখতে পরীক্ষামূলক পতাকাটি জিসিসিতে দেওয়া -frounding-mathযেতে পারে।

উপসংহার

ঝনঝন এবং জিসিসি , এমনকি -O3, আইইইই -৫4৪ অনুসারী। এর অর্থ এটি আইইইই -754 মানক এর উপরোক্ত নিয়মাবলী অনুসরণ করা আবশ্যক। x+0.0হয় বিট-অভিন্ন না করতে xসকলের জন্য xযারা নিয়ম অধীন, কিন্তু x*1.0 তাই হতে করার জন্য চয়ন করা যেতে পারে : যখন আমরা, যথা

  1. xযখন এটি এনএএন হয় তখন অপরিবর্তিত পে-লোডটি পাস করার প্রস্তাবটি মেনে চলুন ।
  2. কোনও NaN ফলাফলের সাইন বিটটি অপরিবর্তিত রেখে দিন * 1.0
  3. ভাগফল / পণ্য চলাকালীন সাইন বিটটি XOR করার আদেশ মেনে চলুন, যখন কোনও এনএএন xহয় না

আইইইই -754-অনিরাপদ অপ্টিমাইজেশান সক্ষম করতে (x+0.0) -> x, পতাকাটি -ffast-mathক্ল্যাং বা জিসিসিতে পাস করা দরকার।


2
কেভেট: এটি যদি সিএএনএল সিএনএন হয়? (আমি আসলে ভেবেছিলাম যে এটি কোনও কারণ হতে পারে, তবে আমি কীভাবে জানি না, তাই আমি জিজ্ঞাসা করেছি।)
ব্যবহারকারী541686

6
@ মেহরদাদ: আনেক্স এফ, সি স্ট্যান্ডার্ডের (alচ্ছিক) অংশ যা আইইইই 754 এর সি আনুগত্যকে নির্দিষ্ট করে, স্পষ্টতই সিএনএলিং এনএএনগুলি কভার করে না। (C11 F.2.1।, প্রথম লাইন: "এই স্পেসিফিকেশন NaNs সিগন্যাল করার আচরণকে সংজ্ঞায়িত করে না।") আনেকেক্স এফের সাথে আনুষ্ঠানিকতা ঘোষণা করে এমন বাস্তবায়নগুলি এনএএন সংকেত দিয়ে তারা যা করতে চায় তা করতে মুক্ত থাকে। সি ++ স্ট্যান্ডার্ডের আইইইই 754 এর নিজস্ব হ্যান্ডলিং রয়েছে, তবে এটি যাই হোক না কেন (আমি পরিচিত নই), আমি সন্দেহ করি এটি NaN আচরণকে সংকেত নির্দিষ্ট করে।
ব্যবহারকারী 2357112

2
@ মেহরদাদ: এসএনএএন মান অনুসারে অপরিজ্ঞাত আচরণের জন্য আহ্বান জানায় (তবে এটি সম্ভবত প্ল্যাটফর্ম দ্বারা ভালভাবে সংজ্ঞায়িত করা হয়েছে) সুতরাং এখানে সংকলক স্কোয়াশ করার অনুমতি রয়েছে।
জোশুয়া

1
@ ব্যবহারকারী 2357112: অন্যথায় অব্যবহৃত গণনার জন্য পার্শ্ব-প্রতিক্রিয়া হিসাবে ত্রুটি-ফাঁদে ফেলার সম্ভাবনা সাধারণত প্রচুর অপটিমাইজেশনে হস্তক্ষেপ করে; যদি কোনও গণনার ফলাফলকে মাঝে মাঝে উপেক্ষা করা হয়, কোনও সংকলক ফলাফলটি কার্যকরভাবে ব্যবহৃত হবে কিনা তা জানতে না পারলে গণনাটি কার্যকরভাবে পিছিয়ে দিতে পারে, তবে যদি গণনাটি একটি গুরুত্বপূর্ণ সংকেত তৈরি করত তবে এটি খারাপ হতে পারে।
supercat

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

35

x += 0.0যদি xহয় তবে NOOP নয় -0.0। অপ্টিমাইজারটি যেভাবে যাইহোক পুরো লুপটি কেটে ফেলতে পারে, যদিও ফলাফলগুলি ব্যবহার করা হয় না। সাধারণভাবে, কোনও অপ্টিমাইজার কেন সিদ্ধান্ত নেয় তা বলা মুশকিল।


2
আমি কেন কেবলx += 0.0 কোনও অপ্স নয় তা পড়ার পরে এটি পোস্ট করেছি , তবুও আমি ভেবেছিলাম সম্ভবত কারণটি নয় কারণ পুরো লুপটি কোনওভাবেই অপ্টিমাইজ করা উচিত। আমি এটি কিনতে পারি, এটি যতটা আশা করি ঠিক
ততটাই দৃ conv়

অবজেক্ট-ওরিয়েন্টেড ভাষাগুলি পার্শ্ব-প্রতিক্রিয়া তৈরি করার প্রবণতা দেওয়া, আমি কল্পনা করব যে অপটিমাইজার প্রকৃত আচরণ পরিবর্তন করছে না তা নিশ্চিত হওয়া কঠিন হবে।
রবার্ট হার্ভে

কারণ হতে পারে, যেহেতু long longঅপ্টিমাইজেশন কার্যকর হয় (এটি জিসিসি দিয়ে তৈরি হয়েছিল, যা কমপক্ষে দ্বিগুণ জন্য একই আচরণ করে )
e2-e4

2
@ রিংø: long longএকটি ইন্টিগ্রাল টাইপ, কোনও আইইইই 7575৫ টাইপ নয়।
এমসাল্টারস 22:44

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