PDA

View Full Version : گفتگو: کدام کد بهینه تر است؟



hossein-khoshseyar
پنج شنبه 29 مرداد 1388, 10:17 صبح
دوستان کسی می دونه که از بین دو تا کد زیر کدوم بهینه تره و سریعتر اجرا می شه
لطفا اول جواب بدبد بعد اگه خواستید برید تست کنید ؟
خیلی عجیب نه ؟
کسی می تونه دلیل منطقی بیاره

کد اول


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

:گیج::گیج::گیج:

majid_vb_2008
پنج شنبه 29 مرداد 1388, 12:57 عصر
سلام فكر مي كنم كد اولي چون دستور


Dim n, m As Int32

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

hossein-khoshseyar
پنج شنبه 29 مرداد 1388, 14:20 عصر
مسئله اینجاست که منم مثل شما فکر می کردم ولی متاسفانه این طور نیست
متاسفانش به خاطر اینه که نمی تونم بفهمم چرا
کسی می تونه کمکمون کنه ؟

Hossis
پنج شنبه 29 مرداد 1388, 14:25 عصر
فکر کنم دومی سریعتر باشه چون دو متغیر داخل روال تعریف شده و با هر بار اجرای حلقه و تابع، متغیر فراموش شده و حافظه خالی می شود اما در اولی ،‌ حافظه به مقدار زیادی اشغال می گردد

tabatabaeefar
پنج شنبه 29 مرداد 1388, 14:30 عصر
سلام
توي اولي هر دوتا متغير m,n يك بار تعريف ميشن.
اما توي دومي m يك بار و n تعداد 10000 بار تعريف خواهند شد.
بايد توجه داشت كه در دومي نميتوان از m,n در خارج از حلقه ها استفاده كرد.
موفق باشيد.

hossein-khoshseyar
پنج شنبه 29 مرداد 1388, 14:31 عصر
فکر کنم دومی سریعتر باشه چون دو متغیر داخل روال تعریف شده و با هر بار اجرای حلقه و تابع، متغیر فراموش شده و حافظه خالی می شود اما در اولی ،‌ حافظه به مقدار زیادی اشغال می گردد

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

hossein-khoshseyar
پنج شنبه 29 مرداد 1388, 14:36 عصر
سلام
توي اولي هر دوتا متغير m,n يك بار تعريف ميشن.
اما توي دومي m يك بار و n تعداد 10000 بار تعريف خواهند شد.
بايد توجه داشت كه در دومي نميتوان از m,n در خارج از حلقه ها استفاده كرد.
موفق باشيد.

خوب یعنی چی . منظورت اینکه اولی سریعتر اجرا می شه؟ یعنی تو هم مثل ما فکر می کنی ؟
خوب دوست عزیز مثل اینکه تو هم مثل ما داری اشتباه فکر می کنی .
چراش رو نمی دونم . اگه می شه یکی کمک کنه
من 6 سال برنامه نویسی می کنم و شغلم اینه . تو این 6 سال به اندازه این یک ماه به چیزای عجیب تو برنامه نویسی بر نخورده بودم

vb.net2008
پنج شنبه 29 مرداد 1388, 17:37 عصر
فكر كنم متغير هاي m و n توي دومي توي ريجيستر قرار مي گيرند

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

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

tabatabaeefar
شنبه 31 مرداد 1388, 07:52 صبح
ضمن تشكر از آقاي كشاورز،
از همه دوستان به خاطر اظهار نظر اشتباهم عذر ميخوام.

scream666_ss
پنج شنبه 05 شهریور 1388, 13:08 عصر
سلام به همگی‌

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

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

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

vcldeveloper
پنج شنبه 05 شهریور 1388, 16:55 عصر
علّت اصلی‌ سر بحث 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 منتقل بشه، که در این صورت عملیات بیشتر از پیش کند میشه.

ACorvinus
پنج شنبه 05 شهریور 1388, 17:35 عصر
نه دوست عزیز، بحث سر 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 فقط شمارنده ها رو نگه میدارن ؟

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


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

scream666_ss
پنج شنبه 05 شهریور 1388, 17:49 عصر
نه دوست عزیز، بحث سر 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 را فراموش کردم. حالا اگر اطلاعاتم نا درست است شرمندم.

vcldeveloper
جمعه 06 شهریور 1388, 01:15 صبح
تعریف شما از از رجیستر CPU همان منظور من از CASH هست چیزی که شما نوشتید با چیزی که من نوشتم یک معنی را میدهد. اما شاید اشتباه از من باشه، اما در تعریفی که از CASH خوندم رجیستر های CPU همان CASH L1 و چیزی که شما از CASH تعریف کردید همان CASH L2 میشود. که من L1 را فراموش کردم.
خیر، رجیسترهای CPU حتی از L1 Cache هم بالاتر هستند. L1 Cache بعد از رجیسترهای CPU قرار داره، و سرعت دسترسی به آن هم کمتر از سرعت دسترسی به رجیسترهای CPU هست.

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

http://upload.wikimedia.org/wikipedia/commons/9/9d/ComputerMemoryHierarchy.png

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

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

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

pirmard
سه شنبه 10 شهریور 1388, 00:10 صبح
وقتی متغیر حلقه for شما بصورت Local Variable تعریف میشه، کامپایلر مقدار آن را در داخل یکی از رجیسترهای CPU نگهداری میکنه.

یه سوال :
در مورد اولویت ذخیره در رجیستر بین متغیر حلقه و متغیر لوکال در همان اسکوپ آیا تفاوتی وجود داره ؟
یعنی
dim j as int
for i as int = 1 to 2
next

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

pirmard
پنج شنبه 30 مهر 1388, 23:41 عصر
کسی نیست جواب بده ؟

scream666_ss
پنج شنبه 30 مهر 1388, 23:47 عصر
دوست عزیز مطمئناً i بر j ارجعیت دارد. یعنی‌ متغیره حلقه بر متغیره local ارجعیت دارد. البته کامپایلر‌ها متغیر هارا بسته به میزان کاربردشان هم ارجعیت میدهند اما درون یک حلقه متغیره خود حلقه ارجعیت بیشتری دارد

pirmard
جمعه 01 آبان 1388, 00:17 صبح
دوست عزیز مطمئناً i بر j ارجعیت دارد. یعنی‌ متغیره حلقه بر متغیره local ارجعیت دارد. البته کامپایلر‌ها متغیر هارا بسته به میزان کاربردشان هم ارجعیت میدهند اما درون یک حلقه متغیره خود حلقه ارجعیت بیشتری دارد

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

vcldeveloper
جمعه 01 آبان 1388, 07:16 صبح
(جواب بر حسب حدس و گمان نمی خام)
کامپایلر مورد استفاده شما تصمیم میگیره که چه متغیری در رجیستر باشه، بهتر هست. یک قانون کلی وجود نداره که بگیم برای هر کامپایلری حتما فلان رفتار صورت میگیره. در دات نت هم JIT متناسب با سکوی هدف (32 بیتی، 64 بیتی، ویندوز، لینوکس، مک، و غیره) متفاوت پیاده سازی میشه، و لزوما کدی که برای یک سکو تولید میکنه، همان کدی نیست که برای سکوی دیگه تولید میکنه.

pirmard
جمعه 01 آبان 1388, 15:14 عصر
کامپایلر مورد استفاده شما تصمیم میگیره که چه متغیری در رجیستر باشه، بهتر هست. یک قانون کلی وجود نداره که بگیم برای هر کامپایلری حتما فلان رفتار صورت میگیره. در دات نت هم JIT متناسب با سکوی هدف (32 بیتی، 64 بیتی، ویندوز، لینوکس، مک، و غیره) متفاوت پیاده سازی میشه، و لزوما کدی که برای یک سکو تولید میکنه، همان کدی نیست که برای سکوی دیگه تولید میکنه.




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

اون سوالم در راستای این پست شما بود که گفته بودین کانتر حلقه در رجیستر نگهداری میشه (بالفرض که مشکل ضیق رجیستر نباشه)

hosseinkhosravi
جمعه 01 آبان 1388, 16:31 عصر
این یک قیاس مع الفارق است!
نکته ای که همه دوستان از اون غافلند اینه که چون هیچ استفاده ای از متغیرها و آرایه های این روتین نشده، به احتمال قریب به یقین کامپایلر بهینه سازی کرده و کل حلقه for رو حذف می کنه! (by pass) لذا آنچه مورد نظر شماست اتفاق نیفتاده. اگر می خواهید مقایسه بهتری داشته باشید، بعد از حلقه for یکی از المانهای آرایه را به طور تصادفی انتخاب کرده و به کاربر نشان دهید تا کامپایلر حلقه را حذف نکند.
این کار یعنی بهینه سازی (optimization) فرایندی است که در ویژوال C++ (http://p30CodeNevis.ir)‎ به بهترین نحو انجام می شود و موارد ساده ای مانند کد فوق، در سایر زبانها هم مسلما انجام می شود.

scream666_ss
جمعه 01 آبان 1388, 21:26 عصر
این یک قیاس مع الفارق است!
نکته ای که همه دوستان از اون غافلند اینه که چون هیچ استفاده ای از متغیرها و آرایه های این روتین نشده، به احتمال قریب به یقین کامپایلر بهینه سازی کرده و کل حلقه for رو حذف می کنه! (by pass) لذا آنچه مورد نظر شماست اتفاق نیفتاده. اگر می خواهید مقایسه بهتری داشته باشید، بعد از حلقه for یکی از المانهای آرایه را به طور تصادفی انتخاب کرده و به کاربر نشان دهید تا کامپایلر حلقه را حذف نکند.
این کار یعنی بهینه سازی (optimization) فرایندی است که در ویژوال C++‎‎ (http://p30CodeNevis.ir)‎ به بهترین نحو انجام می شود و موارد ساده ای مانند کد فوق، در سایر زبانها هم مسلما انجام می شود.

دوست عزیز جمله‌ی که میگید یکم عجیب بنظر میاد. لطفا این کد را در 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:08 عصر
اون سوالم در راستای این پست شما بود که گفته بودین کانتر حلقه در رجیستر نگهداری میشه (بالفرض که مشکل ضیق رجیستر نباشه)

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

pirmard
جمعه 01 آبان 1388, 23:45 عصر
یه سوال دیگه از آقای کشاورز دارم : این مقید سازی ها در چه زمانی انجام میشه ؟
مثلا در کد زیر :

for i = 1 to 100
print i
next

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

vcldeveloper
شنبه 02 آبان 1388, 03:40 صبح
یه سوال دیگه از آقای کشاورز دارم : این مقید سازی ها در چه زمانی انجام میشه ؟

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

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