سرعت و بازدهی کدهای مختلف 2 (ادامه)
سلام مجدد ...
(قولش را قبل از 24 ساعت داده بودم ولی خوب زودتر حاضر شد:31:)
==============
----- کاهش عملیات Boxing و Unboxing در کد
عملیات boxing و unboxing یک عملیات داخلی فریم وروک است که برای برنامه نویسان C#.Net و VB.Net خودکار انجام میشود و اصلاً متوجه آن نمیشوند (ولی مثلاً برنامه نویسان VC++.Net مجبوراً صراحتاً دستور مربوطه را بنویسند)
دات نت زبانی کاملاً شی گرا است و تا انجا پیش رفته که Struct های ان نیز مطابق اصول شی گرایی هستند ...
تمام Struct های دات نت وراثتی هستند از System.ValueType و آن هم وراثتی است از System.Object
بدین ترتیب سلسه مراتب وراثتی برای Struct ها هم تامین شده که گاهاً میتواند باعث تعجب برنامه نویسان سایر زبانهای شی گرایی گردد.
این کار محاسن زیادی دارد و اجازه شی گرایی یکپارچه را در زبان برنامه نویسی میدهد و خیلی خوب است .
ولی اصول مدیریت داخلی حافظه برای Struct ها با Class ها بسیار بسیار فرق دارد و این در اصل سرچشمه تفاوت این دو ساختار است که من قصد و وقت تشریح ان را ندارم و تاثیری هم در کد ما ندارد.
نکته ای که مهم است ان جا است که دات نت چطور میتواند یک Struct را با یک سیستم مدیریت حافظه متفاوت در یک Object که Class است جای دهد؟؟؟
کنترل این عملیات به صورت خودکار بر عهده محیط CLR است و نام این عملیات box و unbox است.
عمل boxing چیزی شبیه این است ... (شبیه است ولی این طوری نیست!)
کد:
public class box
{
public structtype value;
}
//....
structtype value1 = ...;
object value2 = new box() { value = value1 };
که طی آن یک struct (مثل value1) به یک class (مثل value2) تبدیل میشود.
عمل unboxing چیزی شبیه این است ... (شبیه است ولی این طوری نیست!)
کد:
public class box
{
public structtype value;
}
//....
object value2 ...;
structtype value1 = ((box)value2).value;
که طی آن یک struct که داخل یک object است (مثل value2) به یک struct واقعی و آزاد (مثل value1) تبدیل میشود.
نکته مهم و قابل توجه انجا است که عملیات فوق بسیار بسیار پرسرعت و با بازدهی بالا است و اصلاً با کدهایی که دیدید برابر نیست و مستقیم و با سرعت بالا توسط هسته CLR انجام میشود و در هر اجرای یک کپی بسیار کوچک اطلاعات به حجم Struct هم رخ میدهد.
ولی با وجود پرسرعت بودن، انجام عمل فوق در یک حلقه عظیم میتوانید باعث افت سرعت شود،
مجدد تاکید میکنم که حلقه ای 100 بار انجام شود سرعت را 100 برابر کاهش میدهد و حلقه 1000 و 10000 و ... هم جای خود و در نهایت افزایش صفر مشکل ساز میشود.
کد عملی مثل این نمونه از boxing و unboxing است:
کد:
//C#.Net
int v1 = ...;
object v2 = v1;
int v3 = (int)v2;
'VB.Net
Dim v1 As Integer = ...
Dim v2 As Object = v1
Dim v3 As Integer = DirectCast(v2, Integer)
البته کد فوق به ذات مشکل خاص سرعتی ندارد ولی در حلقه ای که چند صفر ناقابل به ان اضافه کند ... !
ولی کد زیر اصلاً boxing و unboxing نیست : (گرچه ظاهرش یکسان است!)
کد:
//C#.Net
string v1 = ...;
object v2 = v1;
string v3 = (string)v2;
'VB.Net
Dim v1 As String = ...
Dim v2 As Object = v1
Dim v3 As String = DirectCast(v2, String)
چون کد اول Integer بود و Integer یک Struct است ولی String خودش یک Class است و نیازی به boxing ندارد.
نتیجتاً شما باید تا حد امکان از پاسکاری Struct ها به Object ها جلوگیری کنید.
=====
همانطور که اول گفتم شما باید مراقب کدنویسی داخلی ناپیدا توابع آماده هم باشید.
مثلا کد ساده زیر را در نظر بگیرید ...
کد:
//C#.Net
int[] array = new int[512];
int item = 0;
for (int index = array.Length -1 ; index >= 0; --index)
{
array[index] = item++;
}
//...
//بحث اصلاً سر کدهای قبلی تا این نوشته نیست
//...
System.Array.Sort(array);
'VB.Net
Dim array(511) As Integer
Dim item As Integer = 0
For index As Integer = array.Length -1 To 0 Step -1
array(index) = item : item += 1
Next
'...
'بحث اصلاً سر کدهای قبلی تا این نوشته نیست
'...
System.Array.Sort(array)
یک کد ساده مختصر مفید و در اصل یک خطی برای مرتب کردن عناصر یک آرایه ... فقط یک خط ! (فقط تک خط آخری)
حالا اگر بگم تک خط کد فوق در بدترین شرایط باعث ...
- دو حلقه تو در تو مقایسه با حدود 130 هزار مقایسه ...
- 260 هزار box ...
- 260 هزار unbox ...
- جابه جایی و انتقال نزدیک 2MB اطلاعات در RAM میشود ...
حالا چه فکر میکنید؟؟؟
حالا فکر کنید قرار باشد کد فوق در متدی مثل Game.Update قرا داشته باشد و قرار باشد در هر ثانیه 60 باری اجرا شود !!!
برنامه شما در یک ثانیه 120MB اطلاعات را فقط به خاطر همین یک خط دستور در RAM جابه جا خواهد کرد!
حتماً باز هم میگید چرا برنامه کند است!!!
یادتان نرود اکثر کدهای برنامه نویسی شما همان تعداد خط کد ظاهری که شما تایپ میکنید نیستند.
(الگوریتم مرتب سازی یک چیز کلی و استاندارد در همه زبانها است و قرار نیست کاری در مریخ انجام شود، اگر دستور اجرا میکنید نباید انتظار داشته باشید که با جادو و دستور در یک آن در CPU اجرا شود، برای انجام عملیاتها یا شما باید الگوریتم را بنویسید یا کس دیگری قبلاً آن را نوشته و در هر دو صورت این الگوریتم هزینه ای برای اجرا دارد.)
==============
متاسفانه یا خوشبختانه بحث "سرعت و بازدهی کدهای مختلف" همچنان ادامه دارد !!!
(آمدیم یک پست در مورد این مطلب بزنیم ولی حالا ... !)
حداقل دو مطلب دیگر باید بیان شوند و وقت خالی ام فعلاً تمام شد.
Microsoft XNA Game Studio
سلام به همه دوستان و خسته نباشید وقعاً...
باور نکردنیه...الان یه، یه ماهی میشه که دارم میرم تو کار ساخت بازی.....اصلاً نمیدونستم این xna چیه....
بعد یه مدت تحقیق میخواستم از 3d game studio شروع کنم...بعد زیاد تعریف ازش نشنیدم....
بعد یه خورده بیشتر با گوگل ور رفتن...دیدم یه برنامه ای ساخت ماکروسافت به نام XNA هم وجود داره...
که جز تعریف چیزی ازش نشنیدم.... اصلاً هم منبع کافی پیدا نکردم..
یه خورده فکر کردم...گفتم توی انجمن برنامه نویسی این داش حسن یه تاپیک زده بود تحت عنوان xna نبود؟شک کردم ولی دوباره که اومدم مطمعاً شدم....
حالا این از شانس من بود مثل اینکه...جا داره یه تشکر درست و حسابی از داش حسنم بکنم...واقعاً ممنونم بابت زحماتت...لطفاً کارت رو ادامه بده...کارم داره راه میوفته...چون یه ایده دارم باید هر چه سریعتر پیادش کنم.
چند تا سوال داشتم.....
این برنامه XNA رو از کجا میشه گیر آورد؟لطفاً لینک دانلودش رو بزارین....
محیط XNA چطوریه؟
آیا ویژوالیه؟مثلاً آبجتهای سه بعدی رو میتونی توش مشاهده کنی؟مثل 3d game studio.
آیا آبجکت های 3ds max 2009 رو مسقیم با متریال میشه وارد این برنامه کرد؟
آیا روی ویژوال استادیو نصب میشه؟
کسی منبعی برای خرید این برنامه یا آموزشش رو داره؟من شدیداً نیاز دارم...
آیا این برنامه فقط برای ساخت بازیه؟لطفاً بیشتر توضیح بدید...
اون لینک کتابهایی که دوستان برای دانلود گذاشتن رو دانلود کردم از همتون ممنونم.اگه میتونین بازم کتاب معرفی کنید..مهم نیست که انگلیسی باشه...فقط آموزشی باشه..
با تشکر فراوان....
ممنون و موفق باشید..
سرعت و بازدهی کدهای مختلف 3 و 4
سلام
==============
----- مصرف صحیح منابع و آزاد سازی به موقع
سلام
تا حد امکان سعی کنید اشیایی را که امکان دارد و مشکلی ایجاد نمیکنند یکبار new کنید و اشاره گر مربوطه را نگه داری کنید و بارها مصرف کنید.
(مثلاً رعایت مورد فوق در مورد Connection های دیتابیس و برنامه های شبکه ای با تراکنش بالا مشکل ایجاد میکند و باید Connection خیلی دیر new و خیلی زود Dispose شود.)
حتماً تدابیری اتخاذ کنید تا اشیایی که دارای واسط System.IDisposable هستند در پایان استفاده نابود شوند و حافظه تخصیص یافته برای مصارف آتی فوراً آزاد شود.
اگر شی ای که واسط System.IDisposable دارد را در یک متد و روال تعریف و استفاده کرده اید و چرخه حیات آن وابسته به همان متد است حتماً حتماً حتماً از دستور Using در دو زبان فوق الذکر استفاده کنید:
کد:
//C#.Net
using (var x = new class1())
{
//...
}
'VB.Net
Using x As New class1()
'...
End Using
در صورتی که شی مورد نظر عمومی و در سطح کلاستان تعریف شده، برای کلاس خود واسط System.IDisposable را پیاده سازی کنید تا تضمینی باشد بر نابودی اشایی فوق در زمان نابودی کلاس خودتان.
اگر درست عمل کنید یک زنجیره محکم نابود سازی و آزاد سازی منابع خواهید داشت ...
بالاخره برنامه از متد Main و با نمونه سازی XNA.Game آغاز میشود و در زیر برنامه Main هم تعریف خود XNA.Game با دستور Using بوده، پس میتوانید در Dispose کلاس XNA.Game خودتان اشیای عمومی تعریف شده را هم نابود کنید و در Dispose هر کدام از انها هم باز زیر اشیای دیگر را نابود کنید
کد:
//C#.Net
public class Class1
{
//...
}
public class Class2
:System.IDisposable
{
private disposableobjecttype a;
private Class1 b;
//...
public void Dispose()
{
if (this.a != null) this.a.Dispose();
System.GC.SuppressFinalize(this);
}
}
public class Class3
: System.IDisposable
{
private System.IDisposable c;
private Class2 d;
private Class1 e;
private object f;
//...
public void Dispose()
{
if (this.c != null) this.c.Dispose();
if (this.d != null) this.d.Dispose();
System.GC.SuppressFinalize(this);
}
}
'VB.Net
Public Class Class1
'...
End Class
Public Class Class2
Implements System.IDisposable
Private a As disposableobjecttype
Private b As Class1
'...
Public Sub Dispose() Implements System.IDisposable.Dispose
If (Me.a IsNot Nothing) Then Me.a.Dispose
System.GC.SuppressFinalize(Me)
End Sub
End Class
Public Class Class3
Implements System.IDisposable
Private c As System.IDisposable
Private d As Class2
Private e As Class1
Private f As Object
'...
Public Sub Dispose() Implements System.IDisposable.Dispose
If (Me.c IsNot Nothing) Then Me.c.Dispose
If (Me.d IsNot Nothing) Then Me.d.Dispose
System.GC.SuppressFinalize(Me)
End Sub
End Class
==============
----- ساده سازی عبارات و استفاده از الگوریتم بهینه تر
در صورت امکان بخشهایی که زیاد پردازش شده و تعداد قابل ملاحظه ای اجرا دارند را ساده کنید و به جای فراخوانی تودرتوی سایر توابع خودتان همانجا مقادیر را محاسبه کنید.
مثلاً نیاز به مربع طول یک بردار دارید ...
مثلاً در نمونه زیر کمی کد دوم بهتر است!
کد:
//C#.Net
XNA.Vector3 v = ...;
float lensq = v.LengthSquared();
float lensq = v.X * v.X + v.Y * v.Y + v.Z * v.Z;
//VB.Net
Dim v As XNA.Vector3 = ...
Dim lensq As Single = v.LengthSquared()
Dim lensq As Single = v.X * v.X + v.Y * v.Y + v.Z * v.Z
البته این فقط نمونه بود و تاثیر چندانی ندارد ولی اگر توان ریاضی اش را داشتید در جاهای خاص میتوانید چند ضرب ماتریس را روی کاغذ خلاصه کنید و از فرمول خلاصه تان استفاده کنید.
=====
در خصوص الگوریتم هم که توضیح خاصی نمیخواهد و فکر کنم همه متوجه هستند ...
در برنامه نویسی هم مثل ریاضی برای انجام یک عملیات میتوان کدهای مختلفی نوشت،
برای بخش های عملیاتی و پردازشی سعی کنید فکر کنید و بهترین کد را که با کمترین هزینه کار مطلوب را انجام میدهد بنویسید.
==============
یک پست دیگر در خصوص "سرعت و بازدهی کدهای مختلف" خواهیم داشت و سپس خواهیم رفت سراغ مبانی ریاضی و هندسه سه بعدی.
رعایت تمام موارد بیان شده در چهارچوب "سرعت و بازدهی کدهای مختلف" تا اینجا در سایر برنامه های غیر سه بعدی هم خوب است و باعث افزایش بازدهی و شفافیت کد خواهد شد.
ولی تاکید میکنم و باز تاکید میکنم که مطالب پست بعدی را فقط و فقط برای برنامه نویسی سه بعدی مثل XNA رعایت کنید و انجام دهید و از انجام آن در سایر برنامه نویسی ها و کدها خودداری کنید چون مطالب پست بعدی که میخواهم بگویم چندان با قواعد برنامه نویسی ساختار یافته مطابقت ندارد ولی در برنامه های سه بعدی به علت وجود حجم بالای پردازش رعایت آن مهم است.
(در سایر برنامه نباید دستورات و روش های گفته شده در پست بعدی من اجرا شود.)
==============
نقل قول:
چند تا سوال داشتم.....
عجیبه پستهای قبلی را ندیده اید؟:31:
نقل قول:
این برنامه XNA رو از کجا میشه گیر آورد؟لطفاً لینک دانلودش رو بزارین....
کسی منبعی برای خرید این برنامه یا آموزشش رو داره؟من شدیداً نیاز دارم...
کامل در پست 8 همین تاپیک لینک ها موجود هستند.
همانطور که بیان شد آموزش یا کتاب درست و حسابی فارسی وجود ندارد.
چند pdf تکه و پاره که یک یا چند تابع را توضیح دادند و تمام. باید از منابع انگلیسی آنلاین یا pdf ای معرفی شده در پست 8 و 11 استفاده کنید.
نقل قول:
محیط XNA چطوریه؟
آیا ویژوالیه؟مثلاً آبجتهای سه بعدی رو میتونی توش مشاهده کنی؟مثل 3d game studio.
آیا روی ویژوال استادیو نصب میشه؟
مفصل در پست 7 همین تاپیک توضیح داده شده.
نقل قول:
آیا آبجکت های 3ds max 2009 رو مسقیم با متریال میشه وارد این برنامه کرد؟
پنجمین هدف آموزشی این تاپیک در پست اول
نقل قول:
آیا این برنامه فقط برای ساخت بازیه؟لطفاً بیشتر توضیح بدید...
مفصل در پست 6 توضیح داده شده.
نقل قول:
اگه میتونین بازم کتاب معرفی کنید..مهم نیست که انگلیسی باشه...فقط آموزشی باشه
طبق چیزهایی که من دیدم فقط در حال حاضر فقط یک کتاب XNA3.0 در اینترنت وجود دارد که در تاپیک لینک داده نشده، یعنی جدید است و فعلاً لینک غیر قانونی ندارد!
راستی جالب است که این تاپیک را در دو تالار فارسی دیگر هم زدم، در یکی از انها به علت همین pdf ها اخطار دادند که چرا لینک دانلود pdf دادید! :31:
سرعت و بازدهی کدهای مختلف 5
سلام
----- کاهش انتقال اطلاعات در حافظه پشته
(اخطار! این مطلب را فقط باید در برنامه نویسی های سه بعدی رعایت کنید و عدم رعایت و پیاده سازی این مطالب در سایر برنمامه ها سودش بیشتر از ضررش است!)
محل استاندارد نگه داری و ذخیره Struct ها در حافظه پشته است.
و حتماً میدانید که این به نوعی مختص همان متدی است که الآن دارد اجرا میشود.
نتیجتاً برای انتقال اطلاعات به/از متد رایانه مجبور میشود دیتاها را جابه جا کند و به پشته مناسب دیگر انتقال بدهد.
(این مطلب ربط خاصی به زبان و محیط برنامه نویسی هم ندارد و تقریباً در همه زبانهای برنامه نویسی وجود دارد)
به تابع زیر دقت کنید:
کد:
//C#.Net
public structtyep1 Func1(structtype2 x, ref structtype3 y, classtype z)
{
//...
}
'VB.Net
Public Function Func1(ByVal x As structtype2, ByRef y As structtype3, ByVal z As classtype) As structtyep1
'...
End Function
این یک تابع نمونه است که سه پارامتر میگیرد و یک پارامتر پس میدهد...
نتیجتاً و کلاً 4 پارامتر ورودی خروجی دارد که باید به/از پشته منتقل شود.
اما هر آرگومان ورودی خروجی فوق چه حجم کپی را به سیستم تحمیل میکند؟
1- آرگومان x:
تعداد بایتهای کپی برابر حجم بایتی struct است
(مثلاً
int=float=4Byte
datetime=double=8Byte
XNA.Vector3=12Byte
XNA.Matrix=64Byte
و...
)
2- آرگومان y:
چون byref است فقط اشاره گرش کپی میشود که در یک سیستم 32 بیتی 32 بیت و برابر 4 بایت است.
یعنی بدون توجه به حجم struct و نوع ان فقط 4 بایت اشاره گر منتقل میشود.
3- آرگومان z:
چون class است و اصلاً ربطی به پشته ندارد، فقط همان اشاره گر 4 بایتی اش کپی میشود.
4- آرگومان بازگشتی از نوع structtype1
مثل آرگومان x است و به اندازه حجمش کپی میشود البته در جهت عکس x که چندان فرقی ندارد!
خوب حالا نتیجه ؟
نتیجه اخلاقی(!)، فلسفی(!)، علمی مطلب فوق ان است که اگر struct ای بخواهد به تابعی پاس داده شود و یا گرفته شود، و اگر ان struct بزرگتر از 4 بایت (و ترجیحاً بزرگتر از 8 بایت) باشد ارجاع اشاره گری آن بهتر و بهینه تر است و حجم کمتری پردازش و هزینه را در بر دارد.
البته ارسال اشاره گری این خطر بزرگ را دارد که عمدی یا سهوی و یا با خطا و... مقدار متغییر در داخل متد و روال تغییر کند در حالی که ما اصلاً نمیخواستیم این مقدار در متد عوض شود و میخواستیم فقط ان را بخواند...
ولی خوب یک کم اگر حواستان جمع باشد و اعتماد داشته باشید در برنامه های سه بعدی خوب است!
مایکروسافت هم در همین جهت در توابع خود دو دسته کد و ورودی خروجی را سازمان داده ...
به دو کد زیر دقت کنید:
کد:
//C#.Net
XNA.Vector3 v1, v2, v3;
//کد اول
//public static XNA.Vector3 Cross(XNA.Vector3 vector1, XNA.Vector3 vector2);
v3 = XNA.Vector3.Cross(v1, v2);
//کد دوم
//public static void Cross(ref XNA.Vector3 vector1, ref XNA.Vector3 vector2, out XNA.Vector3 result);
XNA.Vector3.Cross(ref v1, ref v2, out v3)
'VB.Net
Dim v1, v2, v3 As XNA.Vector3
'کد اول
'Public Shared Function Cross(ByVal vector1 As XNA.Vector3, ByVal vector2 As XNA.Vector3) As XNA.Vector3
v3 = XNA.Vector3.Cross(v1, v2)
'کد دوم
'Public Shared Sub Cross(ByRef vector1 As XNA.Vector3, ByRef vector2 As XNA.Vector3, <Out> ByRef result As XNA.Vector3)
XNA.Vector3.Cross(v1, v2, v3)
این دو کد دقیقاً یک عمل را انجام میدهند.
ولی کد اول در حالت تئوری حداقل 36 بایت را در عملیات خود کپی میکند در حالی که کد دوم در حالت تئوری فقط موجب کپی 12 بایت میشود!
=====
اگر خودتان میخواهید توابعی با الگوی ورودی خروجی دوم بنویسید و در پروژه تان استفاده کنید ... باید باید باید حواستان باشد و مطمئن مطمئن شوید که در نوشتن تابعی با الگوی دوم اشتباهاً مقدار یک پارامتر ورودی byref را در کد تغییر ندهید.
یک مثال دیگر از ضرب سه ماتریس به دو روش!
کد:
//C#.Net
XNA.Matrix m1, m2, m3, m4;
//کد اول
m4 = m1 * m2 * m3;
//کد دوم
XNA.Matrix t;
XNA.Matrix.Multiply(ref m1, ref m2, out t);
XNA.Matrix.Multiply(ref t, ref m3, out m4);
'VB.Net
Dim m1, m2, m3, m4 As XNA.Matrix
'کد اول
m4 = m1 * m2 * m3
'کد دوم
Dim t As XNA.Matrix
XNA.Matrix.Multiply(m1, m2, t)
XNA.Matrix.Multiply(t, m3, m4)
این دو کد دقیقاً یک نتیجه دارند ولی برخلاف ظاهر دو کد مطمئن باشید کد دوم بسیار سریعتر اجرا میشود.
کد اول در حالت تئوری حداقل موجب 384 بایت انتقال اطلاعات در پشته میشود ولی کد دوم در حالت تئوری فقط موجب 24 بایت انتقال اطلاعات بین پشته میشود !!!!!! (حساب نکنید! 16 برابر کمتر میشود!)
بحث سر تفاوت 360 تک بایت نیست ...
1- مشکل سر همان حلقه های پنهانی است که اغلب متوجه شان نمیشودی ولی باعث میشود یک خط کد شما در برنامه های سه بعدی بارها و بارها و بارها اجرا شود و صفرهای ناقابل را در جلوی هزینه ها اضافه کند!
2- قطره قطره جمع گردد و بانگهی دریا شود.
(
البته این را هم اضافه کنم که به علت سادگی بیشتر کد اول و درک راحت تر آن در کدهای اتی این آموزش احتمالاً از همان کد اول استفاده خواهد شد و کدهای آتی ارائه شده در این اموزش لزوماً بهترین کدها نیستند و در این تاپیک اولویت با سادگی و قابل فهم بیشتر بودن کدها خواهد بود.
نتیجتاً شما باید این موارد را رعایت کنید ولی من برای کدهای این تاپیک شاید در جهت منافع آموزشی انها را رعایت نکنم.
به این میگن حق وتوی دات نتی! :31::blink:
)
=====
قرار بود این مطلب آخری در خصوص سرعت و بازدهی باشد ولی دلم نمی آید مطلب را ناقص بگذارم، چون مطمئن هستم اگر نگویم دوستان جای دیگری یا نخواهند دید یا کمتر میبینند کسی این مطالب را شرح دهد.
البته بدیهی است که خیلی از دوستان هم این مطالب را بهتر از من میدانند و به انها تسلط کامل دارند ...
ولی بحرحال به عنوان مطلب پایانی این بحث باید یک پست و مطلب دیگر را توضیح دهم تا حداقل خودم به درجه رضایت نسبی برسم!:11:
سرعت و بازدهی کدهای مختلف 6 (بخش پایانی)
سلام
----- طراحی اشیای مناسب در 3DMax و استفاده صحیح از Texture
این مطلب چندان ربطی به کدنویسی ندارد ولی بسیار بسیار مرتبط با طراحی برنامه های سه بعدی است.
برای ساخت یک شبیه ساز یا بازی یا هر برنامه سه بعدی، شما نیاز به یکسری اشیا سه بعدی طراحی شده در نرم افزارهای سه بعدی دارید.
ولی اشیا استفاده شده در برنامه های نرم افزاری سه بعدی با اشیای طراحی شده توسط یا سه بعدی کار ماهر لزوماً یکی نیست.
مثلاً ...
اگر شما به اغلب سه بعدی کارها بگویید برایتان یک ماشین یا تانک یا ساختمان و... طراحی کنند که در بازی تان استفاده کنید، آنها میتوانند شی مورد نظر شما را با تمام جزئیات و کامل در داخل 3dmax طراحی کنند!
که شی نهایی بسیار زیبا و خوش ساخت هم خواهد بود ولی اغلب این اشیا ارزش کاربردی در برنامه های سه بعدی ندارند!!!
یک سه بعدی کار به صورت عادی وقتی میخواهد یک چرخ ماشین را بسازد، آن را دقیق با بلوک ها و اجزای سه بعدی می سازد!
وقتی میخواهد یک ساختمان را بسازد، آجر به آجر را ساخته و تکثیر میکند و حتی فاصله بین آجرها و شیارهای پنجره و... را هم سه بعدی می سازد.
اگر قرار باشد زنجیر یک تانک را طراحی کند، دقیقاً بلوکهای ذنجیر را ساخته و آنها را در امتداد محل تکثیر میکند.
این قبیل کارها بسیار زیبا هستند ولی برای کار بازی سازی مطلقاً فاقد ارزش هستند!!!
آن فرد متخصص سه بعدی کار میخواهد یک تک ماشین را با 100 یا 200 هزار یا فیشتر فیس روی رایانه خودش که معمولاً بسیار هم قوی است ببیند و آخر سر هم چهار ستون رایانه و RAM و CPU و HDD و VGA و... میلزد تا یک دانه ماشین او را روی مانیتور نشان دهد!!!
حالا شما فکر کنید بخواهید 10 یا 100 تا از ان ماشین یا تانک یا آدم یا ساختمان و... را در بازی خود لود کنید و تازه کلی مخلفات اضافه هم داشته باشید (سایر اشیا و زمین و ساختمانها و درختها و شهر و...)
آنگاه بدون شک برای اجرای بازی شما به جای 500M حافظه نیاز به یک رایانه با 5GB حافظه و به جای کارت گرافیک 512MB یک کارت گرافیکی 500GB نیاز خواهید داشت!!!!
اگر شما به بازی های روز و قوی فعلی نگاه مهندسی معکوس وار (و نه نگاهی از سر لذت و کیف بردن از بازی!) بیاندازید متوجه نکته کوچک و البته بسیار مهمی در تفاوت اشیای استفاده شده توسط این بازیها میشوید.
در تمام بازیها برای پیاده سازی جزئیات یک شی از تصویرهایی استفاده میشود که روی سطح را مثل یک کاغذ دیواری میپوشانند.
یعنی اگر بتوانید روی چرخ ماشین زوم کنید (مثلاً در بازیهای سبک استراتژیک) متوجه میشود سطح چرخ کاملاً صاف است و جزئیات پیچ و مهره و آج های لاستیک و... در واقع تصاویری هستند که روی سطح کشیده شده اند.
یا اگر روی زنجیر تانکی زوم کنید متوجه میشود زنجیر هم صاف است ولی رویش یک عکس الگو دار کشیده شده.
دیوار و پنجره و... ساختمانها هم همه تصویری هستند که روی یک سطح صاف کشیده شده اند.
حتی در بازیهای استراتژیک روی سربازان مسلسلچی هم زوم کنید متوجه میشوید قطار گلوگه ها که از تفنگ آویزان است در واقع یک سطح دو بعدی است که رویش تصویر گلوله نقش بسته.
یا اگر به لوله تانکی دقت کنید به نظر سوراخ می آید ولی وقتی زوم میکنید متوجه میشوید که سوراخ نیست و یک تصویر گرد که وسطش سیاه است را روی لوله گذاشته اند که از دور تداعی سواراخ را میکند.
(نمونه دیوار زیر فقط تصویر معمولی و عادی هستند که روی سطح کشیده شده اند)
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
شما باید تا حد امکان زوایاو جزئیات واقعی سه بعدی اشیا را کاهش دهید و به جایش ان جزئیات را روی تصاویر روکش شده برای اشیا بیاورید.
چون هر زاویه و جزئیات سه بعدی منابع سیستم و کارت گرافیکی را مصرف میکند ولی برای رایانه فرقی ندارد که تصویر روکش ساده باشد یا رنگارنگ باشد!
پیشنهاد میکنم با در نظر گرفتن مطلب فوق و با نگاه دقیق تر یک بازی رایانه یا پلی استیشن و ... را دقیق بررسی کنید و اشیا را برسی کنید از نزدیک ترین فاصله ببینید!
(به فکر بردن نباشید! خیالتان راحت اگر بازی را باختید ایراد ندارید میتوانید دوباره اجرایش کنید! :31:)
========================================
نقل قول:
نوشته شده توسط dogtag
- میشه تمام Struct Type ها رو نام ببرید. (فکر کنم قبلاً گفتید، ولی کامل می خوام)
آخه مگه یکی دو تا است! صدها struct و هزاران class داریم!
در VB و #C و رد بخش کد نویسی روی هر نوعی که خواستید راست کلیک کنید و گزینه Go to Definition را بزنید.
VB پنجره ObjectBrowse را باز میکند و #C هم یک هدر از نوع را، میتوانید ببینید struct است یا class .
نقل قول:
نوشته شده توسط dogtag
آخه برای من یک کم نا مفهومه!
خب هر Typeی یک Class ه دیگه!
هم Int یک Type ه و هم Vector3 و هم کلاسی که خودمان نوشته باشم!
شیوه مدیریت و نگه داری اطلاعات در حافظه برای struct ها با class ها در همه زبانهای برنامه نویسی متفاوت است.
strcut ها در حافظه پشته مخصوص همان متد جاری تخصیص داده میشوند و class ها در یک حافظه جداگانه و مشترک.
نتیجتاً struct ها در زمان ورود و خروج از متد ها و توابع و... باید مجدد به پشته جدید کپی شوند و به همین علت است که وقتی struct را به صورت عادی به متدی پاس میدهید تغییرات آن متد روی struct تاثیری در توابع بالاسری و فراخوان ندارد، چون هر کدام کپی خودشان را دارند.
نقل قول:
نوشته شده توسط dogtag
حتی Struct هم خودش یک کلاسه! (البته فکر کنم. یا حداقل میشه به عنوان یک کلاس ازش استفاده کرد!)
همانطور که قبلاً و در پست 27 گفتم:
نقل قول:
نوشته شده توسط _H2_
دات نت زبانی کاملاً شی گرا است و تا انجا پیش رفته که Struct های ان نیز مطابق اصول شی گرایی هستند ...
تمام Struct های دات نت وراثتی هستند از System.ValueType و آن هم وراثتی است از System.Object
از نظر وراثتی و سلسه مراتب شی گرایی دات نت میتوان گفت Struct هم یک شی هستند و وراثتی از class هستند
ولی مدیریت حافظه همان است که در بالا گفتم و پست 34 گفتم
و انتقال اطلاعات بین struct و کلاس پایه object هم در پست 27 بیان شد.
به نظر من که خیلی شفاف است!
نقل قول:
نوشته شده توسط dogtag
2- الان خیلی زوده! ولی این Vector4 چیه؟ آخه زمان ما فقط 3 تا بردار جهت بود! چهارمی اش چیه؟!
خیالتان راحت! همیشه فقط و فقط سه بردار و محور داریم و لاغیر! اصلاً من خودم از مخالفان سرسخت این بحث های بیشتر از سه بعدی هستم!
ولی مقصود XNA اصلاً اینها نبود!
در خیلی از موارد برنامه نویسی سه بعدی ما نیاز به یک بردار و یک عدد داریم که میتوانستیم چنین پکش کنیم:
کد:
public struct V4
{
public XNA.Vector3;
public float Value;
}
ولی XNA آن را به صورت XNA.Vector4 که میبینید پک کرده که این کار ضمن داشتن مفهوم ریاضی بیشتر و قابلیت انجام محاسبات ترکیبی با ماتریس ها، سادگی را هم همراه دارد.
از جمله مواردی که نیاز به بردار و یک عدد داریم میتوان به چرخش اشیا حول یک بردار مشخص با زاویه مشخص اشاره کرد یا معادله صفحه در فضای سه بعدی که فرمول ان در ریاضی یک بردار نرمال دارد و یک عدد موسوم به D است ( البته نوع ویژه ای برای آن داریم XNA.Plane) و...
کلاً هر کجا نیاز به یک بردار و یک عدد دیگر هم در کنار ان باشد میتوانید برای پک کردن و یکجا نگه داشتن و محاسبه و انتقال به متدهای دیگر و... از XNA.Vector4 استفاده کنید.
(خیلی شبیه دنیای واقعی فیزیک که به علت دخیلی بودن زمان در اغلب محاسبات، فیزیکدانان می آیند و زمان را هم به عنوان بعد چهارم در محاسبات در نظر میگیرند و دنیا را با زمان چهاربعدی فرض میکنند)
-پایان بحث سرعت و بازدهی-
مطالب بعدی در خصوص پیش نیازهای ریاضی خواهد بود.
==============
یک مژده هم به دوستانی که XNA را شروع کرده ام بدهم!
همانطور که حتماً متوجه شده اید XNA از نمایش runtime متون string از RightToLeft پشتیبانی نمیکند و به صورت runtime قادر به نمایش متون فارسی و عربی نیستید ...
البته میتوانید کلمات و عبارات خود را عکس و تصویر کنید و در برنامه نشان دهید که این کار خیلی ساده تر و البته سریعتر هم است ولی بحرحال فعلاً runtime نمیتوانید یک string فارسی را نمایش دهید!
اما مژده اش !!!
من توانستم تابعی جدیدی برای این امر نوشته و با موفقیت هم آزمایشش کنم که اجازه میدهد به همان سادگی نمایش متون انگلیسی و با همان دستورات و بدون دنگ و فنگ بتوانید متون فارسی را هم نمایش دهید. :20:
انشا ا... در محل مناسب و در امکانات ghnet.xna.dll معرفی خواهد شد.
موفق باشید.