কেন 0.1x থেকে 0 পরিবর্তন 10x দ্বারা কর্মক্ষমতা কমিয়ে দেয়?


1527

কেন এই বিট কোড,

const float x[16] = {  1.1,   1.2,   1.3,     1.4,   1.5,   1.6,   1.7,   1.8,
                       1.9,   2.0,   2.1,     2.2,   2.3,   2.4,   2.5,   2.6};
const float z[16] = {1.123, 1.234, 1.345, 156.467, 1.578, 1.689, 1.790, 1.812,
                     1.923, 2.034, 2.145,   2.256, 2.367, 2.478, 2.589, 2.690};
float y[16];
for (int i = 0; i < 16; i++)
{
    y[i] = x[i];
}

for (int j = 0; j < 9000000; j++)
{
    for (int i = 0; i < 16; i++)
    {
        y[i] *= x[i];
        y[i] /= z[i];
        y[i] = y[i] + 0.1f; // <--
        y[i] = y[i] - 0.1f; // <--
    }
}

নিম্নলিখিত বিটের চেয়ে 10 গুণ বেশি দ্রুত চালনা করুন (উল্লিখিত ব্যতীত অভিন্ন)?

const float x[16] = {  1.1,   1.2,   1.3,     1.4,   1.5,   1.6,   1.7,   1.8,
                       1.9,   2.0,   2.1,     2.2,   2.3,   2.4,   2.5,   2.6};
const float z[16] = {1.123, 1.234, 1.345, 156.467, 1.578, 1.689, 1.790, 1.812,
                     1.923, 2.034, 2.145,   2.256, 2.367, 2.478, 2.589, 2.690};
float y[16];
for (int i = 0; i < 16; i++)
{
    y[i] = x[i];
}

for (int j = 0; j < 9000000; j++)
{
    for (int i = 0; i < 16; i++)
    {
        y[i] *= x[i];
        y[i] /= z[i];
        y[i] = y[i] + 0; // <--
        y[i] = y[i] - 0; // <--
    }
}

ভিজ্যুয়াল স্টুডিও 2010 এসপি 1 দিয়ে সংকলন করার সময়। অপ্টিমাইজেশন স্তরটি সক্ষম -02সহ ছিল sse2। আমি অন্য সংকলকগুলির সাথে পরীক্ষা করিনি।


10
আপনি পার্থক্যটি কীভাবে পরিমাপ করলেন? এবং সংকলন করার সময় আপনি কোন বিকল্পগুলি ব্যবহার করেছিলেন?
জেমস কানজে

158
এই ক্ষেত্রে সংকলকটি কেবল +/- 0 টি নামছে না কেন ?!?
মাইকেল ডরগান

127
@ জাইএক্স 2000 সংকলকটি এই নির্বোধের কাছাকাছি কোথাও নেই। LINQPad শো একটি তুচ্ছ উদাহরণ এটি একই কোড কিনা আপনি ব্যবহার spits আউট disassembling 0, 0f, 0d, অথবা এমনকি (int)0একটি প্রেক্ষাপটে যেখানে একটি doubleপ্রয়োজন।
মিলিমুজ

14
অপ্টিমাইজেশন স্তর কি?
অটো অলমেঞ্জিংগার

উত্তর:


1615

অস্বীকৃত ভাসমান পয়েন্টের বিশ্বে স্বাগতম ! পারফরম্যান্সে তারা সর্বনাশ করতে পারে !!!

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

আপনি 10,000 পুনরাবৃত্তিও পর সংখ্যার প্রিন্ট আউট থাকেন তবে আপনি সেই তারা কিনা নির্ভর করে বিভিন্ন মান converged আছে দেখতে হবে 0বা 0.1ব্যবহার করা হয়।

এখানে এক্স কোডে সংকলিত পরীক্ষার কোডটি রয়েছে:

int main() {

    double start = omp_get_wtime();

    const float x[16]={1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.1,2.2,2.3,2.4,2.5,2.6};
    const float z[16]={1.123,1.234,1.345,156.467,1.578,1.689,1.790,1.812,1.923,2.034,2.145,2.256,2.367,2.478,2.589,2.690};
    float y[16];
    for(int i=0;i<16;i++)
    {
        y[i]=x[i];
    }
    for(int j=0;j<9000000;j++)
    {
        for(int i=0;i<16;i++)
        {
            y[i]*=x[i];
            y[i]/=z[i];
#ifdef FLOATING
            y[i]=y[i]+0.1f;
            y[i]=y[i]-0.1f;
#else
            y[i]=y[i]+0;
            y[i]=y[i]-0;
#endif

            if (j > 10000)
                cout << y[i] << "  ";
        }
        if (j > 10000)
            cout << endl;
    }

    double end = omp_get_wtime();
    cout << end - start << endl;

    system("pause");
    return 0;
}

আউটপুট:

#define FLOATING
1.78814e-007  1.3411e-007  1.04308e-007  0  7.45058e-008  6.70552e-008  6.70552e-008  5.58794e-007  3.05474e-007  2.16067e-007  1.71363e-007  1.49012e-007  1.2666e-007  1.11759e-007  1.04308e-007  1.04308e-007
1.78814e-007  1.3411e-007  1.04308e-007  0  7.45058e-008  6.70552e-008  6.70552e-008  5.58794e-007  3.05474e-007  2.16067e-007  1.71363e-007  1.49012e-007  1.2666e-007  1.11759e-007  1.04308e-007  1.04308e-007

//#define FLOATING
6.30584e-044  3.92364e-044  3.08286e-044  0  1.82169e-044  1.54143e-044  2.10195e-044  2.46842e-029  7.56701e-044  4.06377e-044  3.92364e-044  3.22299e-044  3.08286e-044  2.66247e-044  2.66247e-044  2.24208e-044
6.30584e-044  3.92364e-044  3.08286e-044  0  1.82169e-044  1.54143e-044  2.10195e-044  2.45208e-029  7.56701e-044  4.06377e-044  3.92364e-044  3.22299e-044  3.08286e-044  2.66247e-044  2.66247e-044  2.24208e-044

দ্বিতীয় রানটিতে কীভাবে সংখ্যাগুলি শূন্যের খুব কাছাকাছি রয়েছে তা নোট করুন।

অস্বীকৃতিযুক্ত সংখ্যাগুলি সাধারণত বিরল এবং সুতরাং বেশিরভাগ প্রসেসর এগুলি দক্ষতার সাথে পরিচালনা করার চেষ্টা করেন না।


এটিকে কোডের শুরুতে যুক্ত করে ডেনারমালগুলি শূন্যে ফেলা হলে ডেনারমালাইজড সংখ্যার সাথে এর সম্পর্কযুক্ত রয়েছে তা দেখাতে :

_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);

তারপরে সংস্করণটি 0আর 10x ধীর হয় না এবং আসলে দ্রুত হয়। (এটির জন্য এসএসই সক্ষম হওয়া কোডটি সংকলন করা দরকার))

এর অর্থ এই যে প্রায় অল্প শূন্য মানের এই অদ্ভুত নিম্নতর নির্ভুলতা ব্যবহার করার পরিবর্তে আমরা কেবল শূন্যের পরিবর্তে গোল করব।

সময়: কোর আই 7920 @ 3.5 গিগাহার্টজ:

//  Don't flush denormals to zero.
0.1f: 0.564067
0   : 26.7669

//  Flush denormals to zero.
0.1f: 0.587117
0   : 0.341406

শেষ পর্যন্ত, এটি কোনও পূর্ণসংখ্যা বা ভাসমান-পয়েন্ট কিনা তা দিয়ে আসলেই এর কোনও সম্পর্ক নেই। 0বা 0.1fরূপান্তরিত / উভয় loops একটি রেজিস্টার বাহিরে মধ্যে সংরক্ষিত হয়। সুতরাং এটির পারফরম্যান্সে কোনও প্রভাব নেই।


100
আমি এখনও এটি কিছুটা অদ্ভুত খুঁজে পাচ্ছি যে ডিফল্টরূপে সংকলক দ্বারা "+ 0" সম্পূর্ণরূপে অনুকূলিত হয় নি। তিনি যদি "+ 0.0f" রাখতেন তবে কি এটি ঘটত?
s73v3r

51
@ s73v3r এটি একটি খুব ভাল প্রশ্ন। এখন যে আমি সমাবেশ দেখছি, এমনকি + 0.0fঅপ্টিমাইজডও হয় না। যদি আমার অনুমান করতে হয় তবে এটি হতে পারে + 0.0fপার্শ্ব প্রতিক্রিয়াগুলি যদি y[i]সংকেত NaNবা কিছু হয়ে থাকে তবে ... আমি ভুল হতে পারি।
রহস্যময়

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

16
@ আইসাক কারণ যখন y [i] ০.১ এর তুলনায় উল্লেখযোগ্য পরিমাণে ছোট হয় তখন এটি নির্ভুলতার ক্ষতি হয় কারণ সংখ্যায় সর্বাধিক উল্লেখযোগ্য অঙ্ক উচ্চতর হয়।
ড্যান ইজ ফিডলিং ফায়ারলাইট

167
@ s73v3r: + 0.f অপ্টিমাইজ করা যায় না কারণ ভাসমান-পয়েন্টের একটি নেতিবাচক 0 থাকে এবং + 0.f--0f এ যোগ করার ফলাফল + 0.f হয়। সুতরাং 0.f যোগ করা কোনও পরিচয় অপারেশন নয় এবং এটি অপ্টিমাইজ করা যায় না।
এরিক পোস্টপিসিল

415

ব্যবহার gccএবং উত্পন্ন সমাবেশ উৎপাদনের শুধুমাত্র এই পার্থক্য করার জন্য একটি পরিবর্তন প্রয়োগ:

73c68,69
<   movss   LCPI1_0(%rip), %xmm1
---
>   movabsq $0, %rcx
>   cvtsi2ssq   %rcx, %xmm1
81d76
<   subss   %xmm1, %xmm0

cvtsi2ssqএক 10 বার হচ্ছে ধীর প্রকৃতপক্ষে।

স্পষ্টতই, floatসংস্করণটি মেমরি থেকে লোড হওয়া একটি এক্সএমএম রেজিস্টার ব্যবহার করে , যখন intসংস্করণটি অনেক সময় নেয়, নির্দেশকে ব্যবহার করে একটি বাস্তব intমান 0 রূপান্তর floatকরে cvtsi2ssq। জিসিসিতে পাস -O3করা কোনও উপকার করে না। (জিসিসি সংস্করণ ৪.২.১।)

(ব্যবহার doubleপরিবর্তে floatব্যাপার না ছাড়া যে এটা পরিবর্তন cvtsi2ssqএকটি মধ্যে cvtsi2sdq।)

হালনাগাদ

কিছু অতিরিক্ত পরীক্ষা দেখায় যে এটি প্রয়োজনীয়ভাবে cvtsi2ssqনির্দেশনা নয়। একবার মুছে ফেলা ( পরিবর্তে একটি ব্যবহার করে int ai=0;float a=ai;এবং ব্যবহার aকরা 0), গতির পার্থক্য থেকে যায়। সুতরাং @ মিস্টিয়ালটি ঠিক আছে, ডেনারমালাইজড ফ্লোটগুলি পার্থক্য তৈরি করে। এর মধ্যে 0এবং এর মধ্যে মানগুলি পরীক্ষা করে দেখা যায় 0.1f। উপরের কোডটির টার্নিং পয়েন্টটি প্রায় আনুমানিক হয় 0.00000000000000000000000000000001, যখন লুপগুলি হঠাৎ করে 10 বার বেশি সময় নেয়।

আপডেট << 1

এই আকর্ষণীয় ঘটনাটির একটি ছোট্ট দৃশ্যায়ন:

  • কলাম 1: প্রতিটি ফ্লাইটের জন্য 2 দ্বারা বিভক্ত একটি ফ্লোট
  • কলাম 2: এই ফ্লোটের বাইনারি উপস্থাপনা
  • কলাম 3: এই ভাসমানটির 1e7 বার যোগ করতে সময় নেওয়া হয়েছিল

যখন আপনি ডেনোরালাইমাইজেশন সেট করেন তখন আপনি স্পষ্টতই (সর্বশেষ 9 বিট) তার সর্বনিম্ন মানটিতে পরিবর্তন দেখতে পাবেন। সেই সময়ে, সহজ সংযোজন 20 গুণ ধীর হয়ে যায়।

0.000000000000000000000000000000000100000004670110: 10111100001101110010000011100000 45 ms
0.000000000000000000000000000000000050000002335055: 10111100001101110010000101100000 43 ms
0.000000000000000000000000000000000025000001167528: 10111100001101110010000001100000 43 ms
0.000000000000000000000000000000000012500000583764: 10111100001101110010000110100000 42 ms
0.000000000000000000000000000000000006250000291882: 10111100001101110010000010100000 48 ms
0.000000000000000000000000000000000003125000145941: 10111100001101110010000100100000 43 ms
0.000000000000000000000000000000000001562500072970: 10111100001101110010000000100000 42 ms
0.000000000000000000000000000000000000781250036485: 10111100001101110010000111000000 42 ms
0.000000000000000000000000000000000000390625018243: 10111100001101110010000011000000 42 ms
0.000000000000000000000000000000000000195312509121: 10111100001101110010000101000000 43 ms
0.000000000000000000000000000000000000097656254561: 10111100001101110010000001000000 42 ms
0.000000000000000000000000000000000000048828127280: 10111100001101110010000110000000 44 ms
0.000000000000000000000000000000000000024414063640: 10111100001101110010000010000000 42 ms
0.000000000000000000000000000000000000012207031820: 10111100001101110010000100000000 42 ms
0.000000000000000000000000000000000000006103515209: 01111000011011100100001000000000 789 ms
0.000000000000000000000000000000000000003051757605: 11110000110111001000010000000000 788 ms
0.000000000000000000000000000000000000001525879503: 00010001101110010000100000000000 788 ms
0.000000000000000000000000000000000000000762939751: 00100011011100100001000000000000 795 ms
0.000000000000000000000000000000000000000381469876: 01000110111001000010000000000000 896 ms
0.000000000000000000000000000000000000000190734938: 10001101110010000100000000000000 813 ms
0.000000000000000000000000000000000000000095366768: 00011011100100001000000000000000 798 ms
0.000000000000000000000000000000000000000047683384: 00110111001000010000000000000000 791 ms
0.000000000000000000000000000000000000000023841692: 01101110010000100000000000000000 802 ms
0.000000000000000000000000000000000000000011920846: 11011100100001000000000000000000 809 ms
0.000000000000000000000000000000000000000005961124: 01111001000010000000000000000000 795 ms
0.000000000000000000000000000000000000000002980562: 11110010000100000000000000000000 835 ms
0.000000000000000000000000000000000000000001490982: 00010100001000000000000000000000 864 ms
0.000000000000000000000000000000000000000000745491: 00101000010000000000000000000000 915 ms
0.000000000000000000000000000000000000000000372745: 01010000100000000000000000000000 918 ms
0.000000000000000000000000000000000000000000186373: 10100001000000000000000000000000 881 ms
0.000000000000000000000000000000000000000000092486: 01000010000000000000000000000000 857 ms
0.000000000000000000000000000000000000000000046243: 10000100000000000000000000000000 861 ms
0.000000000000000000000000000000000000000000022421: 00001000000000000000000000000000 855 ms
0.000000000000000000000000000000000000000000011210: 00010000000000000000000000000000 887 ms
0.000000000000000000000000000000000000000000005605: 00100000000000000000000000000000 799 ms
0.000000000000000000000000000000000000000000002803: 01000000000000000000000000000000 828 ms
0.000000000000000000000000000000000000000000001401: 10000000000000000000000000000000 815 ms
0.000000000000000000000000000000000000000000000000: 00000000000000000000000000000000 42 ms
0.000000000000000000000000000000000000000000000000: 00000000000000000000000000000000 42 ms
0.000000000000000000000000000000000000000000000000: 00000000000000000000000000000000 44 ms

এআরএম সম্পর্কে সমতুল্য আলোচনা স্ট্যাক ওভারফ্লো প্রশ্নে পাওয়া যাবে উদ্দেশ্য-সি-তে অস্বীকৃত ভাসমান পয়েন্ট?


27
-Oএটি ঠিক করে না, তবে -ffast-mathকরে। (আমি ব্যবহার সব সময় আইএমও কোণ ক্ষেত্রে যেখানে এটি স্পষ্টতা কষ্ট ঘটায় আপ একটি সঠিকভাবে পরিকল্পিত প্রোগ্রাম চালু করা উচিত নয় যাহাই হউক না কেন।)
leftaroundabout

Gcc-4.6 সহ কোনও ইতিবাচক অপ্টিমাইজেশন স্তরে কোনও রূপান্তর নেই।
জেদ

@ লেফটারাউন্ডাবাউট: এমএক্সসিএসআর এফটিজেড -ffast-math(শূন্য থেকে ফ্লাশ) এবং ডিএজেড (ডেনরমাল শূন্য) নির্ধারণ করে এমন কিছু অতিরিক্ত স্টার্টআপ কোডের সাথে লিঙ্কগুলির সাথে একটি এক্সিকিউটেবল (লাইব্রেরি নয়) সংকলন করছেন, সুতরাং সিপিইউকে কখনই ডেনোরমালসের জন্য ধীর মাইক্রোকোড সহায়তা নিতে হবে না।
পিটার

34

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

  • কিছু জিসিসি পরিবেশে কাজ নাও করতে পারে:

    // Requires #include <fenv.h>
    fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
  • কিছু ভিজ্যুয়াল স্টুডিও পরিবেশে কাজ নাও করতে পারে: 1

    // Requires #include <xmmintrin.h>
    _mm_setcsr( _mm_getcsr() | (1<<15) | (1<<6) );
    // Does both FTZ and DAZ bits. You can also use just hex value 0x8040 to do both.
    // You might also want to use the underflow mask (1<<11)
  • জিসিসি এবং ভিজ্যুয়াল স্টুডিও উভয় ক্ষেত্রেই প্রদর্শিত হবে:

    // Requires #include <xmmintrin.h>
    // Requires #include <pmmintrin.h>
    _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
    _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
  • ইন্টেল সংকলকটি আধুনিক ইনটেল সিপিইউগুলিতে ডিফল্টরূপে ডেনারমালগুলি অক্ষম করার বিকল্প রয়েছে। আরও বিশদ এখানে

  • সংকলক সুইচ। -ffast-math, -msseবা -mfpmath=sseডেনারমালগুলি অক্ষম করবে এবং আরও কয়েকটি জিনিস দ্রুত তৈরি করবে, তবে দুর্ভাগ্যক্রমে প্রচুর অন্যান্য অনুমানগুলিও করতে পারে যা আপনার কোডটি ভঙ্গ করতে পারে। সাবধানে পরীক্ষা! ভিজ্যুয়াল স্টুডিও সংকলকটির জন্য দ্রুত-গণিতের সমতুল্য /fp:fastতবে আমি এটি নিশ্চিত করতে সক্ষম হইনি যে এটি ড্যানোরার্মগুলিও অক্ষম করে। 1


1
এটি ভিন্ন তবে সম্পর্কিত প্রশ্নের উত্তর দেওয়ার মতো শোনায় (আমি কীভাবে সংখ্যার গণনাগুলি ডেনররমাল ফল উত্পন্ন হতে বাধা দিতে পারি?) যদিও এই প্রশ্নের উত্তর দেয় না doesn't
বেন ভয়েগট

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

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

18

জিসিসিতে আপনি এফটিজেড এবং ডিএজেড সক্ষম করতে পারবেন:

#include <xmmintrin.h>

#define FTZ 1
#define DAZ 1   

void enableFtzDaz()
{
    int mxcsr = _mm_getcsr ();

    if (FTZ) {
            mxcsr |= (1<<15) | (1<<11);
    }

    if (DAZ) {
            mxcsr |= (1<<6);
    }

    _mm_setcsr (mxcsr);
}

এছাড়াও জিসিসি সুইচগুলি ব্যবহার করুন: -msse -mfpmath = sse

(কার্ল হিথারিংটনের সাথে সংশ্লিষ্ট ক্রেডিট [1])

[1] http://carlh.net/plugins/denormals.php


আরো দেখুন fesetround()থেকে fenv.h(rounding আরো পোর্টেবল উপায় (C99 জন্য সংজ্ঞায়িত) অন্য জন্য, linux.die.net/man/3/fesetround ) (কিন্তু এই সব FP অপারেশন শুধু subnormals না প্রভাবিত করবে, )
জার্মান গার্সিয়া

আপনি কি নিশ্চিত যে এফটিজেডের জন্য আপনার <<< 15 এবং 1 << 11 প্রয়োজন? আমি কেবল 1 << 15 অন্য কোথাও উদ্ধৃত দেখেছি ...
ডুমুর

@ ফিগ: 1 << 11 আন্ডারফ্লো মাস্কের জন্য। এখানে আরও তথ্য: সফটপিক্সেল
জার্মান গার্সিয়া

@ জার্মানগার্সিয়া এটি ওপিএস প্রশ্নের উত্তর দেয় না; প্রশ্নটি ছিল "কেন এই বিট কোডটি, এর চেয়ে 10 গুণ বেশি দ্রুত চলে ..." - আপনি হয় উত্তর দেওয়ার চেষ্টা করতে হবে এই কার্যকারিতাটি সরবরাহ করার আগে বা একটি মন্তব্যে এটি সরবরাহ করার আগে।

9

ড্যান নীলের মন্তব্যটি একটি উত্তরে প্রসারিত হওয়া উচিত:

এটি শূন্য ধ্রুবক নয় 0.0fযা অস্বীকৃত বা ধীরগতির কারণ হয়, এটি লুপের প্রতিটি পুনরাবৃত্তির শূন্যের কাছে পৌঁছানো মানগুলি। যেহেতু তারা শূন্যের কাছাকাছি এবং কাছাকাছি আসে, তাদের প্রতিনিধিত্ব করার জন্য আরও নির্ভুলতার প্রয়োজন এবং তারা অস্বীকৃতিতে পরিণত হয়। এই y[i]মানগুলি। (এগুলি শূন্যের কাছে পৌঁছায় কারণ x[i]/z[i]সকলের জন্য 1.0 এর চেয়ে কম is i)

কোডটির ধীর এবং দ্রুত সংস্করণের মধ্যে গুরুত্বপূর্ণ পার্থক্যটি হল বিবৃতি y[i] = y[i] + 0.1f;। এই লাইনটি লুপের প্রতিটি পুনরাবৃত্তির সম্পাদন করা মাত্রই, ফ্লোটের অতিরিক্ত সূক্ষ্মতাটি নষ্ট হয়ে যায় এবং সেই নির্ভুলতার প্রতিনিধিত্ব করার জন্য ডেনরমালাইজেশন প্রয়োজন হয় না। এরপরে, ভাসমান পয়েন্ট অপারেশনগুলি y[i]দ্রুত থাকে কারণ তারা অস্বীকৃত নয়।

আপনি যুক্ত করার পরে অতিরিক্ত নির্ভুলতা কেন হারিয়ে যায় 0.1f? কারণ ভাসমান পয়েন্ট সংখ্যাগুলিতে কেবলমাত্র এতগুলি উল্লেখযোগ্য অঙ্ক রয়েছে। বলুন আপনি তিনটি গুরুত্বপূর্ণ সংখ্যা, তারপর জন্য যথেষ্ট সঞ্চয়ের স্থান রেয়েছে 0.00001 = 1e-5, এবং 0.00001 + 0.1 = 0.1এই উদাহরণে ভাসা বিন্যাসের অন্তত, কারণ এটি রুমে অন্তত গুরুত্বপূর্ণ বিট সংরক্ষণ করতে নেই 0.10001

সংক্ষেপে, y[i]=y[i]+0.1f; y[i]=y[i]-0.1f;কোন বিকল্প নেই আপনি সম্ভবত এটি মনে করতে পারেন।

মিস্টিকাল এটিও বলেছেন : ভাসমান বিষয়বস্তুগুলি কেবল সমাবেশের কোড নয়।

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