نمایش نتایج 1 تا 29 از 29

نام تاپیک: کدام کد بهینه تر است؟

  1. #1
    کاربر دائمی آواتار hossein-khoshseyar
    تاریخ عضویت
    دی 1387
    محل زندگی
    تهران
    پست
    532

    کدام کد بهینه تر است؟

    دوستان کسی می دونه که از بین دو تا کد زیر کدوم بهینه تره و سریعتر اجرا می شه
    لطفا اول جواب بدبد بعد اگه خواستید برید تست کنید ؟
    خیلی عجیب نه ؟
    کسی می تونه دلیل منطقی بیاره

    کد اول

    Dim n1(11000), m1(11000), j(11000) As Double
    Dim n, m As Int32

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    For m = 1 To 100000
    For n = 0 To 10000
    n1(n) = n
    m1(n) = n
    j(n) = n1(n) * m1(n)
    Next
    Next
    End Sub


    کد دوم


    Dim n1(11000), m1(11000), j(11000) As Double

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    For dim m as int32= 1 To 100000
    For dim n as int32 = 0 To 10000
    n1(n) = n
    m1(n) = n
    j(n) = n1(n) * m1(n)
    Next
    Next
    End Sub


  2. #2
    کاربر دائمی
    تاریخ عضویت
    آبان 1387
    محل زندگی
    مشهد
    پست
    353

    نقل قول: یه نکته خیلی خیلی جالب

    سلام فكر مي كنم كد اولي چون دستور

    Dim n, m As Int32


    يك بار اجرا مي شه

  3. #3
    کاربر دائمی آواتار hossein-khoshseyar
    تاریخ عضویت
    دی 1387
    محل زندگی
    تهران
    پست
    532

    نقل قول: یه نکته خیلی خیلی جالب

    مسئله اینجاست که منم مثل شما فکر می کردم ولی متاسفانه این طور نیست
    متاسفانش به خاطر اینه که نمی تونم بفهمم چرا
    کسی می تونه کمکمون کنه ؟

  4. #4
    کاربر دائمی آواتار Hossis
    تاریخ عضویت
    آبان 1386
    محل زندگی
    بیرجند
    پست
    1,735

    نقل قول: یه نکته خیلی خیلی جالب

    فکر کنم دومی سریعتر باشه چون دو متغیر داخل روال تعریف شده و با هر بار اجرای حلقه و تابع، متغیر فراموش شده و حافظه خالی می شود اما در اولی ،‌ حافظه به مقدار زیادی اشغال می گردد

  5. #5
    کاربر دائمی آواتار tabatabaeefar
    تاریخ عضویت
    اسفند 1387
    محل زندگی
    زمین خدا
    پست
    259

    نقل قول: یه نکته خیلی خیلی جالب

    سلام
    توي اولي هر دوتا متغير m,n يك بار تعريف ميشن.
    اما توي دومي m يك بار و n تعداد 10000 بار تعريف خواهند شد.
    بايد توجه داشت كه در دومي نميتوان از m,n در خارج از حلقه ها استفاده كرد.
    موفق باشيد.

  6. #6
    کاربر دائمی آواتار hossein-khoshseyar
    تاریخ عضویت
    دی 1387
    محل زندگی
    تهران
    پست
    532

    نقل قول: یه نکته خیلی خیلی جالب

    نقل قول نوشته شده توسط Hossis مشاهده تاپیک
    فکر کنم دومی سریعتر باشه چون دو متغیر داخل روال تعریف شده و با هر بار اجرای حلقه و تابع، متغیر فراموش شده و حافظه خالی می شود اما در اولی ،‌ حافظه به مقدار زیادی اشغال می گردد
    آخه ما که بحث حافظه رو مطرح نکردیم . بحث سرعت تازه تو اولی مکه چقد حافظه بیشتر اشغال شده ؟ دو تا متغیر اینتجر تعریف شده دیگه این که جایی نمی گیره. ولی توی دومی این متغیر تو هر بار اجرای حلقه داره دوباره تعریف می شه . با اطلاعاتی که من دارم حدس می زدم اولی سریعتر اجرا بشه ولی تو پست قبلی گفتم که این طور نیست ؟ حالا دنبال یه جواب منطقی می کردم
    کسی می تونه کمک کنه ؟

  7. #7
    کاربر دائمی آواتار hossein-khoshseyar
    تاریخ عضویت
    دی 1387
    محل زندگی
    تهران
    پست
    532

    نقل قول: یه نکته خیلی خیلی جالب

    نقل قول نوشته شده توسط tabatabaeefar مشاهده تاپیک
    سلام
    توي اولي هر دوتا متغير m,n يك بار تعريف ميشن.
    اما توي دومي m يك بار و n تعداد 10000 بار تعريف خواهند شد.
    بايد توجه داشت كه در دومي نميتوان از m,n در خارج از حلقه ها استفاده كرد.
    موفق باشيد.
    خوب یعنی چی . منظورت اینکه اولی سریعتر اجرا می شه؟ یعنی تو هم مثل ما فکر می کنی ؟
    خوب دوست عزیز مثل اینکه تو هم مثل ما داری اشتباه فکر می کنی .
    چراش رو نمی دونم . اگه می شه یکی کمک کنه
    من 6 سال برنامه نویسی می کنم و شغلم اینه . تو این 6 سال به اندازه این یک ماه به چیزای عجیب تو برنامه نویسی بر نخورده بودم

  8. #8

    نقل قول: یه نکته خیلی خیلی جالب

    فكر كنم متغير هاي m و n توي دومي توي ريجيستر قرار مي گيرند

  9. #9

    نقل قول: کدام کد بهینه تر است؟

    اما توي دومي m يك بار و n تعداد 10000 بار تعريف خواهند شد.
    کامپایلر اونقدر باهوش هست که متغیر حلقه را هر بار تعریف نکنه! متغیرهای حلقه هر کدام فقط یک بار توسط کامپایلر تعریف میشند، پس این مورد تاثیری در سرعت اجرای حلقه ها نداره. بطور کلی تعریف متغیر حلقه بصورت Global کار بهینه ایی نیست، حتی برخی کامپایلرها اصلا به شما اجازه این کار را نمی دهند. مثلا در دلفی اگر شما n و m را به شکل کد اول تعریف کنید، و از آنها به عنوان متغیر حلقه for استفاده کنید، کامپایلر به شما هشدار میده، و از شما میخواد که متغیر حلقه را در داخل روتین مربوطه تعریف کنید.

    پس، کد دوم بهینه تر از کد اول است.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  10. #10
    کاربر دائمی آواتار tabatabaeefar
    تاریخ عضویت
    اسفند 1387
    محل زندگی
    زمین خدا
    پست
    259

    نقل قول: کدام کد بهینه تر است؟

    ضمن تشكر از آقاي كشاورز،
    از همه دوستان به خاطر اظهار نظر اشتباهم عذر ميخوام.

  11. #11

    نقل قول: کدام کد بهینه تر است؟

    سلام به همگی‌

    گفتهٔ آقای کشاورز کاملا درسته اما علّت اینکه دومی‌ سریعتر از اولی‌ هست این نیست(البته با عرضه پوزش از آقای کشاورز)

    علّت اصلی‌ سر بحث bus هست. زمانی‌ که یک متغییر درون حلقه باشه در زمان اجرا سیستم کل دستور for به همراه متغیر آن را در CPU Cash بارگذاری می‌کنه اما زمانی‌ که متغیر عضوی از حلقه نباشه سیستم آن را همراه با دستور در Cash بارگذاری نمی‌کنه. بهمین دلیل در کد اول سیستم شما بارها باید متغیر هارا در chash بارگذاری و بد به ram انتقال بده همین مساله زمان CPU را هدر میدهد. اما در کد دوم چون متغیر‌ها عضوی از for هستند پس همزمان با بقیه بدنه for در cash بارگذاری میشوند و تا انتهای حلقه for از cash خارج نمیشون. حالا با یک حساب سر انگشتی میتونید پیدا کنید که سیستم شما در code اول چند بار باید بین ram و cash سفر کنه. و همه میدونیم که سفر بین ram و cash برای cpu زمان بسیار زیادی را تلف می‌کنه. علّت پیغام خطا در زبان delphi هم دقیقا همین مورد هست.

    با تشکر از همگی‌

  12. #12

    نقل قول: کدام کد بهینه تر است؟

    علّت اصلی‌ سر بحث bus هست. زمانی‌ که یک متغییر درون حلقه باشه در زمان اجرا سیستم کل دستور for به همراه متغیر آن را در CPU Cash بارگذاری می‌کنه اما زمانی‌ که متغیر عضوی از حلقه نباشه سیستم آن را همراه با دستور در Cash بارگذاری نمی‌کنه. بهمین دلیل در کد اول سیستم شما بارها باید متغیر هارا در chash بارگذاری و بد به ram انتقال بده همین مساله زمان CPU را هدر میدهد. اما در کد دوم چون متغیر‌ها عضوی از for هستند پس همزمان با بقیه بدنه for در cash بارگذاری میشوند و تا انتهای حلقه for از cash خارج نمیشون. حالا با یک حساب سر انگشتی میتونید پیدا کنید که سیستم شما در code اول چند بار باید بین ram و cash سفر کنه. و همه میدونیم که سفر بین ram و cash برای cpu زمان بسیار زیادی را تلف می‌کنه. علّت پیغام خطا در زبان delphi هم دقیقا همین مورد هست.
    نه دوست عزیز، بحث سر Cache نیست. اولا تعریف متغیر حلقه در داخل تعریف دستور for یا تعریف آن به عنوان یک Local Variable فرقی با هم نمی کنند. وقتی متغیر حلقه for شما بصورت Local Variable تعریف میشه، کامپایلر مقدار آن را در داخل یکی از رجیسترهای CPU نگهداری میکنه. رجیسترهای CPU حکم متغیرهای اختصاصی CPU را دارند، و در داخل خودِ CPU تعبیه شدند، به همین دلیل CPU سریعترین سرعت دسترسی را به آنها دارد. با هر بار گردش حلقه، یک مقدار به رجیستر مربوطه اضافه میشه.
    وقتی متغیر را بصورت Global Variable تعریف می کنید، CPU به آن به عنوان یک خانه ایی از RAM دسترسی پیدا میکنه. این خانه از RAM ممکن هست در Cache موجود باشه، یا نباشه. اگر در Cache موجود باشه، CPU با سرعت بیشتری نسبت به RAM به آن دسترسی پیدا میکنه، ولی همچنان از رجیسترهای CPU کندتر هست. اگر در Cache موجود نباشه، باید از RAM به Cache منتقل بشه، که در این صورت عملیات بیشتر از پیش کند میشه.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  13. #13
    کاربر دائمی
    تاریخ عضویت
    مهر 1387
    محل زندگی
    تهران
    سن
    35
    پست
    608

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    نه دوست عزیز، بحث سر Cache نیست. اولا تعریف متغیر حلقه در داخل تعریف دستور for یا تعریف آن به عنوان یک Local Variable فرقی با هم نمی کنند. وقتی متغیر حلقه for شما بصورت Local Variable تعریف میشه، کامپایلر مقدار آن را در داخل یکی از رجیسترهای CPU نگهداری میکنه. رجیسترهای CPU حکم متغیرهای اختصاصی CPU را دارند، و در داخل خودِ CPU تعبیه شدند، به همین دلیل CPU سریعترین سرعت دسترسی را به آنها دارد. با هر بار گردش حلقه، یک مقدار به رجیستر مربوطه اضافه میشه.
    وقتی متغیر را بصورت Global Variable تعریف می کنید، CPU به آن به عنوان یک خانه ایی از RAM دسترسی پیدا میکنه. این خانه از RAM ممکن هست در Cache موجود باشه، یا نباشه. اگر در Cache موجود باشه، CPU با سرعت بیشتری نسبت به RAM به آن دسترسی پیدا میکنه، ولی همچنان از رجیسترهای CPU کندتر هست. اگر در Cache موجود نباشه، باید از RAM به Cache منتقل بشه، که در این صورت عملیات بیشتر از پیش کند میشه.

    سلام .

    ببخشید، آیا GC در مورد رجیستری های CPU، مثل خانه های RAM عمل می کنه یا خیر ؟

    در ضمن آیا رجیستری های CPU فقط شمارنده ها رو نگه میدارن ؟

  14. #14

    نقل قول: کدام کد بهینه تر است؟

    در ضمن آیا رجیستری های CPU فقط شمارنده ها رو نگه میدارن ؟
    خیر، هر داده ایی که بشه به صورت عدد صحیح منتقل کرد (مثلا اشاره گرها) را می توان در آنها جا داد.

    ببخشید، آیا GC در مورد رجیستری های CPU، مثل خانه های RAM عمل می کنه یا خیر ؟
    منظورتون رو متوجه نمیشم. GC کاری به رجیسترهای CPU نداره. GC مدیریت حافظه Heap مربوط به process شما را برعهده داره، همین.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  15. #15

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    نه دوست عزیز، بحث سر Cache نیست. اولا تعریف متغیر حلقه در داخل تعریف دستور for یا تعریف آن به عنوان یک Local Variable فرقی با هم نمی کنند. وقتی متغیر حلقه for شما بصورت Local Variable تعریف میشه، کامپایلر مقدار آن را در داخل یکی از رجیسترهای CPU نگهداری میکنه. رجیسترهای CPU حکم متغیرهای اختصاصی CPU را دارند، و در داخل خودِ CPU تعبیه شدند، به همین دلیل CPU سریعترین سرعت دسترسی را به آنها دارد. با هر بار گردش حلقه، یک مقدار به رجیستر مربوطه اضافه میشه.
    وقتی متغیر را بصورت Global Variable تعریف می کنید، CPU به آن به عنوان یک خانه ایی از RAM دسترسی پیدا میکنه. این خانه از RAM ممکن هست در Cache موجود باشه، یا نباشه. اگر در Cache موجود باشه، CPU با سرعت بیشتری نسبت به RAM به آن دسترسی پیدا میکنه، ولی همچنان از رجیسترهای CPU کندتر هست. اگر در Cache موجود نباشه، باید از RAM به Cache منتقل بشه، که در این صورت عملیات بیشتر از پیش کند میشه.
    استاد گرامی تعریف شما از از رجیستر CPU همان منظور من از CASH هست چیزی که شما نوشتید با چیزی که من نوشتم یک معنی را میدهد. اما شاید اشتباه از من باشه، اما در تعریفی که از CASH خوندم رجیستر های CPU همان CASH L1 و چیزی که شما از CASH تعریف کردید همان CASH L2 میشود. که من L1 را فراموش کردم. حالا اگر اطلاعاتم نا درست است شرمندم.

  16. #16

    نقل قول: کدام کد بهینه تر است؟

    تعریف شما از از رجیستر CPU همان منظور من از CASH هست چیزی که شما نوشتید با چیزی که من نوشتم یک معنی را میدهد. اما شاید اشتباه از من باشه، اما در تعریفی که از CASH خوندم رجیستر های CPU همان CASH L1 و چیزی که شما از CASH تعریف کردید همان CASH L2 میشود. که من L1 را فراموش کردم.
    خیر، رجیسترهای CPU حتی از L1 Cache هم بالاتر هستند. L1 Cache بعد از رجیسترهای CPU قرار داره، و سرعت دسترسی به آن هم کمتر از سرعت دسترسی به رجیسترهای CPU هست.

    برای اینکه تصویر روشن تری از این موضوع داشته باشید، می تونید تصویر زیر را مشاهده کنید:



    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  17. #17

    نقل قول: کدام کد بهینه تر است؟


    بازهم سلام
    این جمله شما کاملا متین و درست است. اما تا آنجایی که در علم کامپیوتر مطرح است CPU هیچ تعهدی مبنی بر اینکه به یک متغیر اجازه بارگذاری در رجیستر‌های داخلی‌ را بدهد نداشته و به همین دلیل است که در زبانهای سطح پایینتر زمانی‌ که از دستوراتی استفاده می‌کنیم که متغیری را در رجیستر قرار دهیم اعلام میشود که CPU در صورت توان اینکار را خواهد کرد. عموم استفاده رجیستر‌های درجه اول که شما منظورتان است برای خود CPU و مسأیل مربوط به آن استفاده شده و بیشتر CPU اطلاعات سیستمی‌ را وارد آنها خواهد کرد. اما متغیر‌های مانند متغیر درونی حلقه for تضمین میشوند که در بالاترین سطح cash نگهداری شوند. اما هیچ تضمینی برای نگهداری آنها در رجیستر‌های درجه اول نیست. این چیزی است که من خوانده‌ام آیا درسته؟



  18. #18

    نقل قول: کدام کد بهینه تر است؟

    این جمله شما کاملا متین و درست است. اما تا آنجایی که در علم کامپیوتر مطرح است CPU هیچ تعهدی مبنی بر اینکه به یک متغیر اجازه بارگذاری در رجیستر‌های داخلی‌ را بدهد نداشته و به همین دلیل است که در زبانهای سطح پایینتر زمانی‌ که از دستوراتی استفاده می‌کنیم که متغیری را در رجیستر قرار دهیم اعلام میشود که CPU در صورت توان اینکار را خواهد کرد. عموم استفاده رجیستر‌های درجه اول که شما منظورتان است برای خود CPU و مسأیل مربوط به آن استفاده شده و بیشتر CPU اطلاعات سیستمی‌ را وارد آنها خواهد کرد. اما متغیر‌های مانند متغیر درونی حلقه for تضمین میشوند که در بالاترین سطح cash نگهداری شوند. اما هیچ تضمینی برای نگهداری آنها در رجیستر‌های درجه اول نیست. این چیزی است که من خوانده‌ام آیا درسته؟
    بله، ولی این امور سطح پایین دیگه به کامپایلر مربوط نمیشه. بهینه ترین کاری که کامپایلر میتونه انجام بده اینکه کدی تولید کنه که به CPU بگه فلان متغیر برای قرارگیری در فلان رجیستر مناسب هست. این میشه کد بهینه ایی که کامپایلر تولید کرده. حالا اینکه CPU متناسب با شرایط خودش در زمان اجرای آن دستور چه رفتاری از خود نشان می دهد، از کنترل کامپایلر خارج هست.

    همین مسئله درباره کامپایلرهایی که برای برنامه های Multi-threaded بهینه سازی شدند هم صادق هست؛ کامپایلر سعی می کند تا حد امکان کدی تولید کند که CPU بتوانند راحتر آن را به شاخه های مختلف تقسیم کند، ولی تضمینی وجود ندارد که CPU حتما این کار را بکند. بنا بر شرایط CPU در زمان اجرای آن کد، ممکن است CPU به این نتیجه برسند که در حال حاضر امکان اجرای آن کد در مسیرهای مختلف وجود ندارد.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  19. #19

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    وقتی متغیر حلقه for شما بصورت Local Variable تعریف میشه، کامپایلر مقدار آن را در داخل یکی از رجیسترهای CPU نگهداری میکنه.
    یه سوال :
    در مورد اولویت ذخیره در رجیستر بین متغیر حلقه و متغیر لوکال در همان اسکوپ آیا تفاوتی وجود داره ؟
    یعنی
    dim j as int
    for i as int = 1 to 2
    next


    اینجا i , j هر دو در یک محل ذخیره می شوند ؟ (یعنی مثلا هر دو در رجیستر یا هر دو در کش لول1 / حتی اگر ضیق حافظه هم بود i لزوما بر j ارجحیت نداشته باشد.)
    یا اینکه فرقی بین متغیر حلقه و متغیر لوکال وجود داره ؟(مثلا i ارجحیت دارد برای تصاحب حافظه با دسترسی سریعتر)

  20. #20

    نقل قول: کدام کد بهینه تر است؟

    کسی نیست جواب بده ؟

  21. #21

    نقل قول: کدام کد بهینه تر است؟

    دوست عزیز مطمئناً i بر j ارجعیت دارد. یعنی‌ متغیره حلقه بر متغیره local ارجعیت دارد. البته کامپایلر‌ها متغیر هارا بسته به میزان کاربردشان هم ارجعیت میدهند اما درون یک حلقه متغیره خود حلقه ارجعیت بیشتری دارد

  22. #22

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط scream666_ss مشاهده تاپیک
    دوست عزیز مطمئناً i بر j ارجعیت دارد. یعنی‌ متغیره حلقه بر متغیره local ارجعیت دارد. البته کامپایلر‌ها متغیر هارا بسته به میزان کاربردشان هم ارجعیت میدهند اما درون یک حلقه متغیره خود حلقه ارجعیت بیشتری دارد
    خوب این جواب شما دوپهلو بود و من دنبال جواب شفافش هستم
    طبق صحبت صفحه قبل متغیر حلقه در رجسیتر قرار می گیرد. اما یه متغیر لوکال در همان اسکوپ که کانتر حلقه ای هم نیست در رجیستر قرار نمی گیرد .
    آیا حرفهای بالا بدون استثنا درستن ؟
    و اگه یه متغیر حلقه در حلقه ای کاربردش کمتر از یک متغیر لوکال در همان اسکوپ باشد باز هم قانون بالا در مورد آن صدق می کند ؟
    (جواب بر حسب حدس و گمان نمی خام)

  23. #23

    نقل قول: کدام کد بهینه تر است؟

    (جواب بر حسب حدس و گمان نمی خام)
    کامپایلر مورد استفاده شما تصمیم میگیره که چه متغیری در رجیستر باشه، بهتر هست. یک قانون کلی وجود نداره که بگیم برای هر کامپایلری حتما فلان رفتار صورت میگیره. در دات نت هم JIT متناسب با سکوی هدف (32 بیتی، 64 بیتی، ویندوز، لینوکس، مک، و غیره) متفاوت پیاده سازی میشه، و لزوما کدی که برای یک سکو تولید میکنه، همان کدی نیست که برای سکوی دیگه تولید میکنه.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  24. #24

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    کامپایلر مورد استفاده شما تصمیم میگیره که چه متغیری در رجیستر باشه، بهتر هست. یک قانون کلی وجود نداره که بگیم برای هر کامپایلری حتما فلان رفتار صورت میگیره. در دات نت هم JIT متناسب با سکوی هدف (32 بیتی، 64 بیتی، ویندوز، لینوکس، مک، و غیره) متفاوت پیاده سازی میشه، و لزوما کدی که برای یک سکو تولید میکنه، همان کدی نیست که برای سکوی دیگه تولید میکنه.


    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    وقتی متغیر حلقه for شما بصورت Local Variable تعریف میشه، کامپایلر مقدار آن را در داخل یکی از رجیسترهای CPU نگهداری میکنه. رجیسترهای CPU حکم متغیرهای اختصاصی CPU را دارند، و در داخل خودِ CPU تعبیه شدند، به همین دلیل CPU سریعترین سرعت دسترسی را به آنها دارد. با هر بار گردش حلقه، یک مقدار به رجیستر مربوطه اضافه میشه.
    اون سوالم در راستای این پست شما بود که گفته بودین کانتر حلقه در رجیستر نگهداری میشه (بالفرض که مشکل ضیق رجیستر نباشه)

  25. #25

    نقل قول: کدام کد بهینه تر است؟

    این یک قیاس مع الفارق است!
    نکته ای که همه دوستان از اون غافلند اینه که چون هیچ استفاده ای از متغیرها و آرایه های این روتین نشده، به احتمال قریب به یقین کامپایلر بهینه سازی کرده و کل حلقه for رو حذف می کنه! (by pass) لذا آنچه مورد نظر شماست اتفاق نیفتاده. اگر می خواهید مقایسه بهتری داشته باشید، بعد از حلقه for یکی از المانهای آرایه را به طور تصادفی انتخاب کرده و به کاربر نشان دهید تا کامپایلر حلقه را حذف نکند.
    این کار یعنی بهینه سازی (optimization) فرایندی است که در ویژوال C++‎‎ به بهترین نحو انجام می شود و موارد ساده ای مانند کد فوق، در سایر زبانها هم مسلما انجام می شود.

  26. #26

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط hosseinkhosravi مشاهده تاپیک
    این یک قیاس مع الفارق است!
    نکته ای که همه دوستان از اون غافلند اینه که چون هیچ استفاده ای از متغیرها و آرایه های این روتین نشده، به احتمال قریب به یقین کامپایلر بهینه سازی کرده و کل حلقه for رو حذف می کنه! (by pass) لذا آنچه مورد نظر شماست اتفاق نیفتاده. اگر می خواهید مقایسه بهتری داشته باشید، بعد از حلقه for یکی از المانهای آرایه را به طور تصادفی انتخاب کرده و به کاربر نشان دهید تا کامپایلر حلقه را حذف نکند.
    این کار یعنی بهینه سازی (optimization) فرایندی است که در ویژوال C++‎‎‎‎ به بهترین نحو انجام می شود و موارد ساده ای مانند کد فوق، در سایر زبانها هم مسلما انجام می شود.
    دوست عزیز جمله‌ی که میگید یکم عجیب بنظر میاد. لطفا این کد را در VB.Net تست کن تا ببینید که کامپایلر کد حلقه را حذف نمی‌کنه. شاید بتوانید تو تنظیمات،این مساله را طوری تنظیم کنید که اینگونه کدها هنگام کامپایل حذف بشوند اما در حالت رسمی‌ و پیشفرض کامپایلر اجازه حذف هیچ خط کد را از برنامه شما ندارد.
    Label1.Visible = False
    Dim watch As New Stopwatch
    watch.Start()
    For i As Integer = 0 To 999999999
    Next i
    watch.Stop()
    Label1.Text = watch.Elapsed.ToString
    Label1.Visible = True
    آخرین ویرایش به وسیله scream666_ss : جمعه 01 آبان 1388 در 22:20 عصر

  27. #27

    نقل قول: کدام کد بهینه تر است؟

    نقل قول نوشته شده توسط pirmard مشاهده تاپیک
    اون سوالم در راستای این پست شما بود که گفته بودین کانتر حلقه در رجیستر نگهداری میشه (بالفرض که مشکل ضیق رجیستر نباشه)
    دوست عزیز کامپایلر‌ها بقدری پیشرفت شدن که عملا نمی‌شه بطور دقیق گفت که چه کدی را برای شما تولید میکنند. همانطوری که جناب کشاورز فرمودند علاوه بر کد شما چندین شرایط خواسته دیگه هم بررسی می‌شه تا زمان کامپایل چه متغیری کجا قرار بگیره.

  28. #28

    نقل قول: کدام کد بهینه تر است؟

    یه سوال دیگه از آقای کشاورز دارم : این مقید سازی ها در چه زمانی انجام میشه ؟
    مثلا در کد زیر :

    for i = 1 to 100
    print i
    next

    بالفرض مهیا بودن رجیستر و مساعد بودن همه شرایط دیگر! طبق فرمایش شما کانتر حلقه باید در رجیستر قرار بگیره . (اصلا فرض کنید 100 درصد باید در رجیستر قرار بگیره این)
    حال آیا این مقیدسازی این متغیر به قرار گرفتن در رجیستر در کد IL (یعنی زمان کامپایل ) انجام می گیره -چون فرموده بودید به کامپایلر بستگی داره- ؟
    یا زمان اجرا؟-چون فرموده بودید به ماشین مقصد هم بستگی داره-؟

  29. #29

    نقل قول: کدام کد بهینه تر است؟

    یه سوال دیگه از آقای کشاورز دارم : این مقید سازی ها در چه زمانی انجام میشه ؟
    حال آیا این مقیدسازی این متغیر به قرار گرفتن در رجیستر در کد IL (یعنی زمان کامپایل ) انجام می گیره -چون فرموده بودید به کامپایلر بستگی داره- ؟
    اول این نکته را عرض کنم که من برنامه نویس دات نت نیستم، پس از من انتظار نداشته باشید به جزئیات کار اجزاء مختلف دات نت اشراف کامل داشته باشم.

    کد IL ایی که تولید میشه، به درد هیچ ماشین حقیقی نمیخوره، پس قرار گرفتن یک متغیر در رجیستر در زمان تولید کد IL کار خاصی انجام نمیده، پس عمل قرار گرفتن داده در رجیستر CPU باید توسط JIT در زمان اجرا انجام بشه، بخصوص که در زمان تولید کد IL هنوز پلت فرم هدف کاملا مشخص نشده، و معلوم نیست طول حقیقی رجیسترهای CPU مقصد چقدر خواهد بود.
    ولی اینکه آیا در زمان تولید کد IL، داده هایی به کد اضافه میشه تا به JIT بفهمانه چه متغیرهایی برای قرار گرفتند در رجیسترهای CPU ارجحیت دارند، من از آن اطلاعی ندارم.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •