PDA

View Full Version : سوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان



SajjadKhati
دوشنبه 04 آذر 1398, 10:54 صبح
سلام
وقتی از thread و نخ ها استفاده میکنیم ، مگه واقعا از چند هسته بصورت همزمان استفاده میشه؟
یعنی مثلا وقتی دو نخ (مثلا یه نخ اصلی به همراه یه نخ دیگه که کلا بشه 2 تا) را اجرا میکنیم ، در این حالت ، واقعا از 2 هسته (ی منطقی) استفاده میشه؟
اگه نه ، پس چرا در کد زیر ، واقعا از 2 هسته برام استفاده میکنه؟ :



private void TransparentControl4_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(this.NewThreadMethod));
thread.Start();


for (long i = 0; i < 10000000000; i++)
{
}


MessageBox.Show("main thread loop finished");
}


private void NewThreadMethod()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("new thread loop finished");
}


پردازنده ی من i5 4460 هه (4 هسته ی فیزیکی با 4 هسته ی منطقی) و وقتی کد بالا را توش اجرا میکنم ، از 50 درصد توان پردازنده یعنی از 2 هسته اش (یعنی بصورت موازی) استفاده میکنه . زمان اجراش هم تقریبا 25 ثانیه برام بود .
وقتی کد بالا را در یک نخ اجرا میکنم (کد دو تا نخ را توی یکی میزارم) ، یعنی کد زیر را مینویسم :



private void TransparentControl4_Click(object sender, EventArgs e)
{
for (long i = 0; i < 10000000000; i++)
{
}


for (long j = 0; j < 10000000000; j++)
{
}


MessageBox.Show("main thread loop finished");
}



اولا که مشخص هست در یک هسته اجرا میکنه و دوما اینکه زمان اجراش بیش از 55 ثانیه میشه .



اما سئوالم اینه که اولا گاها جاهایی دیدم که میگن که نخ هایی که با هم اجرا میکنیم (مثل کد اولی در بالا) ، بصورت همزمان (در دو یا چند هسته ی فیزیکی یا منطقی) اجرا نمیشن بلکه در 1 هسته ی منطقی اجرا میشن اما سوئیچ روی شون بصورت مدام انجام میشه . پس این گفته ، غلط هه دیگه . درست میگم؟
حالا اگه این نخ ها را به 3 تا نخ برسونین و با هم اجرا کنین ، در 3 هسته (ی منطقی) بصورت همزمان اجرا میشه و 4 تا در 4 هسته و همینطور به تعداد نخ هایی که ایجاد میکنید ، در هسته های منطقی مختلف ، بصورت همزمان اجرا میشه .


و سئوال دوم اینکه پس اگه Thread و نخ ها را وقتی با هم اجرا میکنیم ، توی هسته های مختلف بصورت همزمان اجرا میشن ، پس کلاس Parallel دیگه به چه کاری میاد و به چه دردمون میخوره؟
یا به عبارتی ، بنابراین ، تفاوت کلاس Thread و Parallel در کجاست و چه زمانی از کلاس Thread و چه زمانی از کلاس Parallel استفاده میشه و موارد استفاده ی هر کدوم ، در کجاست؟
چون Parallel را تا جایی که میدونستم برای این بود که کدهاش بصورت موازی در هسته های مختلف ، بصورت همزمان اجرا میشه ، حال اینکه این کار با کلاس Thread هم انجام میشه .


سوم اینکه (هر چند ربط مستقیمی به این سئوالات نداره) درباره ی kernel time در task manager کسی میدونه توضیح بده؟ این ، همون مقدار انتظار یا سربار اون هسته ی منطقی را نمایش میده؟

the king
دوشنبه 04 آذر 1398, 12:44 عصر
وقتی از thread و نخ ها استفاده میکنیم ، مگه واقعا از چند هسته بصورت همزمان استفاده میشه؟

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

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



یعنی مثلا وقتی دو نخ (مثلا یه نخ اصلی به همراه یه نخ دیگه که کلا بشه 2 تا) را اجرا میکنیم ، در این حالت ، واقعا از 2 هسته (ی منطقی) استفاده میشه؟
اگه نه ، پس چرا در کد زیر ، واقعا از 2 هسته برام استفاده میکنه؟ :

اگه منظورتون هسته مجازی باشه، بله میتونه همچین کاری رو انجام بده، اما نمیتونه هسته مجازی اول روی یک هسته فیزیکی باشه و هسته مجازی دوم روی هسته فیزیکی دیگری، باید همسایه هم باشن.



پردازنده ی من i5 4460 هه (4 هسته ی فیزیکی با 4 هسته ی منطقی) و وقتی کد بالا را توش اجرا میکنم ، از 50 درصد توان پردازنده یعنی از 2 هسته اش (یعنی بصورت موازی) استفاده میکنه . زمان اجراش هم تقریبا 25 ثانیه برام بود .
وقتی کد بالا را در یک نخ اجرا میکنم (کد دو تا نخ را توی یکی میزارم) ، یعنی کد زیر را مینویسم :



private void TransparentControl4_Click(object sender, EventArgs e)
{
for (long i = 0; i < 10000000000; i++)
{
}


for (long j = 0; j < 10000000000; j++)
{
}


MessageBox.Show("main thread loop finished");
}



اولا که مشخص هست در یک هسته اجرا میکنه و دوما اینکه زمان اجراش بیش از 55 ثانیه میشه .



اما سئوالم اینه که اولا گاها جاهایی دیدم که میگن که نخ هایی که با هم اجرا میکنیم (مثل کد اولی در بالا) ، بصورت همزمان (در دو یا چند هسته ی فیزیکی یا منطقی) اجرا نمیشن بلکه در 1 هسته ی منطقی اجرا میشن اما سوئیچ روی شون بصورت مدام انجام میشه . پس این گفته ، غلط هه دیگه . درست میگم؟
حالا اگه این نخ ها را به 3 تا نخ برسونین و با هم اجرا کنین ، در 3 هسته (ی منطقی) بصورت همزمان اجرا میشه و 4 تا در 4 هسته و همینطور به تعداد نخ هایی که ایجاد میکنید ، در هسته های منطقی مختلف ، بصورت همزمان اجرا میشه .

چه بخواهیم و چه نخواهیم همیشه سوئیچ داره انجام میشه، توجه به این نکته داشته باشید که پروسه برنامه شما یکی از صدها پروسه ای است که از سیستم عامل میخوان که اجراشون کنه. دائم داره بین نخ هایی که هسته اجرا می کنه سوئیچ صورت میگیره. از هر کدوم چند کد بیشتر اجرا نمیشه و سوئیچ میشه به نخ دیگری. اینکه شما درصد کارکرد رو 50 درصد میبینید به این معنی نیست که نخ های شما 50 درصد توان پردازنده رو گرفتن، اگر اینطور بود که خیلی عالی میشد.
یکی از چالش های طراحی سیستم عامل همینه که تا حد امکان بازدهی رو ببرن بالا ولی هنوز به اون حد نرسیده که بتوانید همچبن بازدهی رو داشته باشید.
متاسفانه اونقدر بازدهی بالا نیست که همچین اتفاقی بیافته. اون چیزی که شما به عنوان درصد میبینید معیار اسمی و ظاهری است، دقت کافی رو نداره.
اگر پردازنده میخواست در هر لحظه حواسش به اون درصد باشه باید یک هسته اش رو مشغول نگه میداشت که اون درصد اشغالی رو بسنجه.
اون چیزی که بهتون نشون میده به این معنی است که در 50 درصد زمان هایی که سنجش صورت گرفته نخ هایی که بیشترین توان پردازنده رو گرفته نخ های برنامه شما است. هیچوقت صد در صد به این معنی نیست که شما صد درصد توان پردازنده رو گرفتید چون اونوقت خود Task Manager و سیستم مدیریت حافطه و مدیریت فایل و ... رو با چه پردازنده ای اجرا کنه؟




و سئوال دوم اینکه پس اگه Thread و نخ ها را وقتی با هم اجرا میکنیم ، توی هسته های مختلف بصورت همزمان اجرا میشن ، پس کلاس Parallel دیگه به چه کاری میاد و به چه دردمون میخوره؟
یا به عبارتی ، بنابراین ، تفاوت کلاس Thread و Parallel در کجاست و چه زمانی از کلاس Thread و چه زمانی از کلاس Parallel استفاده میشه و موارد استفاده ی هر کدوم ، در کجاست؟
چون Parallel را تا جایی که میدونستم برای این بود که کدهاش بصورت موازی در هسته های مختلف ، بصورت همزمان اجرا میشه ، حال اینکه این کار با کلاس Thread هم انجام میشه .

یکی از محدودیت های NET. این بود که شما نخ رو می ساختید ولی برای اجرای چند هسته ای کاری نمی توانستید انجام بدید. Parallel برای همین طراحی شد تا یک مجرایی برای اجرای نخ ها روی هسته های مجزا ایجاد کنه.
اون Parallel این امکان رو به NET. و سیستم عامل میده که به بهترین شکل ممکن و در حدی که محدودیت های معماری پردازنده اجازه میده نخ ها رو بین هسته ها تقسیم کنن، یعنی کاری که شما با نخ سازی نمیتوانید انجام بدید.
پس اگر قصدتون این باشه که از توان چند هسته ای فیزیکی استفاده کنید بجای نخ سازی از Parallel کمک می گیرید.



سوم اینکه (هر چند ربط مستقیمی به این سئوالات نداره) درباره ی kernel time در task manager کسی میدونه توضیح بده؟ این ، همون مقدار انتظار یا سربار اون هسته ی منطقی را نمایش میده؟
پردازنده کد ماشین رو در دو تا مد اجرا میکنه، یک حالت مد هسته است که به سخت افزار دسترسی مستقیم داره و برنامه های هسته سیستم عامل و درایور ها ازش استفاده می کنند و حالت دوم مد کاربر ئه که به سخت افزار دسترسی مستقیم نداره و برنامه هایی عادی ازش استفاده می کنند. اون چیزی که تحت عنوان kernel time میبینید نشون میده که چه بخشی از کارکرد پردازنده برای اجرا شدن کد های مود هسته صرف شده، یعنی فرضا اگه 20 درصد توان پردازنده باشه، نشون میده 20 درصد توان پردازنده برای اجرا شدن کد های برنامه هسته سیستم عامل و درایور ها صرف شده، نه سایر برنامه های عادی و سیستمی.

SajjadKhati
دوشنبه 04 آذر 1398, 15:37 عصر
هسته فیزیکی یا هسته مجازی؟


سلام استاد .
استاد ، خودتونین دیگه ، نه (در انجمن دیگه) ؟
خیلی خوشحال شدم جواب مو دادین . خیلی ممنون استاد . :قلب:
اینترنت هنوز وصل نشد و نمیتونیم مطالب را تحقیق کنیم و توی سایت و انجمنی بریم .

الان استاد ، هسته ی مجازی ، همون هسته ی منطقی بود دیگه؟ درسته؟
هر هسته ی فیزیکی ، حداقل یک هسته ی منطقی داره دیگه . درسته؟
چون توی آمار پردازنده ی خودم مثلا قبلا میرفتم (پردازنده ام i5 4460 هست که 4 هسته ی فیزیکی داره) مینوشت :
4physical core _ 1 logical core per physical
یعنی 4 هسته ی فیزیکی که در هر هسته ی فیزیکی ، 1 هسته ی منطقی (پس 4 هسته ی منطقی) داره دیگه . درسته؟

یا اینکه هر هسته ی فیزیکی میتونه دو هسته ی منطقی داشته باشه که در این صورت ، اون پردازنده ، تکنولوژی Hyper Thread داره مثل i3 4150 (با 2 هسته ی فیزیکی و 4 هسته ی منطقی (که در هر هسته ی فیزیکی اش ، 2 هسته ی منطقی وجود داره)) . درسته؟




بصورت متعارف میتونه روی فرضا دو هسته مجازی دو تا نخ برنامه تون رو همزمان اجرا کنه ولی روی دو هسته فیزیکی نه.


الان ، در کدی که من در بالا دادم (کد اول) ، برنامه ام در 2 هسته ی فیزیکی اجرا شد دیگه . هم گفته بودم توان پردازنده رو 50 درصد (از 4 هسته ی فیزیکی که میشه 2 هسته ی فیزیکی) اشغال کرد و هم نسبت به زمانی که کد دو نخ را در یک نخ نوشتم (و بنابراین در یک هسته که 25 درصد از توان پردازنده را اشغال کرده بود) ، دو برابر سریعتر اجرا شد . یعنی در این حالتِ 2 نخی ، زمان اش 25 ثانیه و در حالتِ تک نخی ، زمانش 55 ثانیه طول کشید (حالا حدودا 3 ثانیه این ورتر یا اون ور تر) .
بجز این ، هر چقدر که نخ جدیدی اجرا میکردم ، توان پردازنده ، 25 درصد (در پردازنده ی 4 هسته ایِ i5 4460) افزایش پیدا میکرد و نسبت به تک نخی ، سرعتش بیشتر میشد . مثلا 3 نخ اجرا میکردم ، توان پردازنده ، 75 درصد برای پروسه ام میشد اما همونطور که گفتین ، در 4 نخ ، به 100 نمیرسید و بین 85 تا 95 درصد میشد .

پس ، بنابراین ، وقتی چند نخی کدنویسی میکنیم ، هر نخ ، داخل یک هسته (ی منطقی یا فیزیکی) اجرا میشن دیگه . (چون پردازنده ی من قابلیت Hyper Thread یا همون وجود 2 هسته ی منطقی در هر هسته ی فیزیکی را نداره) . درسته؟
اگه درست نیست ، پس چرا هسته ها بیشتر مشغول و کدها سریعتر انجام میشن؟




مساله به معماری پردازنده بستگی داره، چون ما در مورد یک پردازنده خاص صحبت نمی کنیم و نمیدونیم در آینده چه تغییری در معماریشون رخ میده جواب ممکنه همیشه نه نباشه.


آها ، یعنی بسته به معماری پردازنده هم میتونه داشته باشه؟
یعنی الان ممکنه یکی این کد بالا (اولی) را در پردازنده ی چند هسته ای اجرا کنه اما در دو هسته اش اجرا نشه؟



از اونجایی که این دو تا هسته مجازی روی یک هسته فیزیکی قرار دارن میتونن دو تا نخ مربوط به پروسه شما رو همزمان اجرا کنند، البته کارکرد پایینتر.


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



دلیل اش اینه که دو تا هسته مجازی نمی توانند کاملا مستقل از هم هر کد ماشینی رو اجرا کنن، مثل این میمونه که هسته فیزیکی یک اتاق خواب داره و یک آشپزخانه.
اتاق خواب رو به یک هسته مجازی میدن و آشپزخونه رو به یک هسته مجازی دیگه. اولی نمیتونه هیچ کدی که به آشپزخونه نیاز داره اجرا کنه و دومی نمیتونه هیچ کدی که به اتاق خواب نیاز داره.

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


بله ، خیلی ممنون این ها رو گفته بودین .
البته ، این تداخل که میگین ، بخاطر این نیست که دو تا هسته ی منطقی وقتی در یک هسته ی فیزیکی وجود دارن ، از حافظه ی مشترکی استفاده میکنند؟ یا اینکه از گذرگاه داده ای مشترکی استفاده میکنند؟
اگه آره ، اون حافظه ، دقیقا چه حافظه ای هست؟ حافظه ی رجیساری در دو هسته ی منطقی ای که در یک هسته ی فیزیکی وجود دارند ، مشترک هست یا حافظه ی کش l1 یا کش l2 یا l3 ؟

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



چه بخواهیم و چه نخواهیم همیشه سوئیچ داره انجام میشه، توجه به این نکته داشته باشید که پروسه برنامه شما یکی از صدها پروسه ای است که از سیستم عامل میخوان که اجراشون کنه. دائم داره بین نخ هایی که هسته اجرا می کنه سوئیچ صورت میگیره. از هر کدوم چند کد بیشتر اجرا نمیشه و سوئیچ میشه به نخ دیگری.


بله ، گفته بودید .
اما همونطور که گفته بودید ، معمولا (نه همیشه) میسنجه که ببینه میزان سربارش میصرفه تا سوئیچ کنه یا نه و بعد سوئیچ میکنه به نخ دیگه .



اینکه شما درصد کارکرد رو 50 درصد میبینید به این معنی نیست که نخ های شما 50 درصد توان پردازنده رو گرفتن، اگر اینطور بود که خیلی عالی میشد.


من دقیق متوجه نشدم .
الان ، نظرتون اینه که کدهای با اونکه 50 درصد از توان (یه پردازنده ی 4 هسته ای) را گرفتن ، اما دارن توی یه هسته اجرا میشن؟
اگه منظورتون اینه ، پس چرا زمان اجراشون هم نسبت به هم (قبلا توضیح دادم) ، تقریبا 2 برابر فرق کرده؟



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


بله میدونم .
task manager اطلاعاتش را در بهترین حالت ، هر نیم ثانیه بروز میکنه در حالی که پردازنده ، یه کد را در یک میلی ثانیه و حتی در حد میکروثانیه اجرا میکنه.
البته ، منظور من ، این قضیه نبود .



یکی از محدودیت های NET. این بود که شما نخ رو می ساختید ولی برای اجرای چند هسته ای کاری نمی توانستید انجام بدید.


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



Parallel برای همین طراحی شد تا یک مجرایی برای اجرای نخ ها روی هسته های مجزا ایجاد کنه.
اون Parallel این امکان رو به NET. و سیستم عامل میده که به بهترین شکل ممکن و در حدی که محدودیت های معماری پردازنده اجازه میده نخ ها رو بین هسته ها تقسیم کنن، یعنی کاری که شما با نخ سازی نمیتوانید انجام بدید.
پس اگر قصدتون این باشه که از توان چند هسته ای فیزیکی استفاده کنید بجای نخ سازی از Parallel کمک می گیرید.


قطعا اگه این کد اول را توی Parallel بنویسیم و توی پردازنده ی چند هسته ای (یا HyperThread) هم اجرا کنیم ، زمان اجراش از حالتی که من کد اول را در دو نخ نوشتم ، بیشتر نمیشه .



پردازنده کد ماشین رو در دو تا مد اجرا میکنه، یک حالت مد هسته است که به سخت افزار دسترسی مستقیم داره و برنامه های هسته سیستم عامل و درایور ها ازش استفاده می کنند و حالت دوم مد کاربر ئه که به سخت افزار دسترسی مستقیم نداره و برنامه هایی عادی ازش استفاده می کنند. اون چیزی که تحت عنوان kernel time میبینید نشون میده که چه بخشی از کارکرد پردازنده برای اجرا شدن کد های مود هسته صرف شده، یعنی فرضا اگه 20 درصد توان پردازنده باشه، نشون میده 20 درصد توان پردازنده برای اجرا شدن کد های برنامه هسته سیستم عامل و درایور ها صرف شده، نه سایر برنامه های عادی و سیستمی.


آها خیلی ممنون استاد . :قلب:

SajjadKhati
دوشنبه 04 آذر 1398, 18:01 عصر
استاد ، من همین کد (کد اول در پست اول) را در Parallel اجرا کردم ، زمان اجراش ، دقیقا مثل همون کد اول ، 24 ثانیه طول کشید (کد اولی هم که گفته بودم 25 ثانیه ، در واقع 24 ثانیه بود . حالا چون بصورت چشمی ، خودم اندازه گیریِ حدودی میکنم ، مهم نیست . فقط کلیات برام مهم هه نه اندازه گیریِ دقیقِ زمان) :



private void NewThreadMethod_1()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("NewThreadMethod_1 loop finished");
}


private void NewThreadMethod_2()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("NewThreadMethod_2 loop finished");
}


private void TransparentControl5_Click(object sender, EventArgs e)
{
Action[] actions = new Action[] { new Action(this.NewThreadMethod_1), new Action(this.NewThreadMethod_2) };
Parallel.Invoke(actions);
}


این هم مثل اون ، 50 درصد از توان پردازنده ام ، یعنی 2 هسته ی فیزیکی (که همون 2 هسته ی منطقی اش هم میشه) را اشغال کرد .

the king
دوشنبه 04 آذر 1398, 21:39 عصر
سلام استاد .
استاد ، خودتونین دیگه ، نه (در انجمن دیگه) ؟

استاد نیستم ولی بله، همونم. این اختلال اینترنت توفیق اجباری شد برای اینکه باز مجددا چند روزی اینجا بیام. البته اینترنت ADSL ام برقرار شده.



الان استاد ، هسته ی مجازی ، همون هسته ی منطقی بود دیگه؟ درسته؟

معنی خیلی نزدیک بهمی دارند ولی دقیقا یکسان نیستند. هسته مجازی مثل سایر مفاهیم داخل سیستم عامل دیدگاه نرم افزاری داره، متفاوته با دیدگاه سخت افزاری که نسبت به پردازنده داریم.
هسته منطقی چیزی است که از ابتدا در ذات پردازنده هست، قابلیتش رو داره و تو معماری و طراحیش وجود داره، فرضا پردازنده ای با چهار هسته فیزیکی که به لطف Hyper-threading جمعا هشت هسته منطقی داره.
اما هسته مجازی تعبیری است که سیستم عامل از هسته داره. معمولا سیستم عامل هر هسته منطقی رو یک هسته مجازی در نظر میگیره و هسته منطقی و مجازی یک معنی پیدا میکنند اما الزاما اینطور نیست، مثلا ممکنه یک سیستم عامل خاصی یا سیستم عامل مجازی با یک معماری نرم افزاری بیاد هر هسته منطقی رو به دو بخش مختلف تقسیم کنه و عملا تعداد هسته های مجازی اش دو برابر بشه، چون کاملا مجازی است و نرم افزاری، دست سیستم عامل تو این موارد باز ئه.



هر هسته ی فیزیکی ، حداقل یک هسته ی منطقی داره دیگه . درسته؟

طبق توصیفی که ما تا به حال از پردازنده ها داشتیم بله، این توقع رو داریم.



چون توی آمار پردازنده ی خودم مثلا قبلا میرفتم (پردازنده ام i5 4460 هست که 4 هسته ی فیزیکی داره) مینوشت :
4physical core _ 1 logical core per physical
یعنی 4 هسته ی فیزیکی که در هر هسته ی فیزیکی ، 1 هسته ی منطقی (پس 4 هسته ی فیزیکی) داره دیگه . درسته؟

بله، به عبارت دیگه در پردازنده ای با این مشخصات هر هسته فیزیکی در هر لحظه صرفا میتونه یک کد ماشین رو اجرا کنه.



یا اینکه هر هسته ی فیزیکی میتونه دو هسته ی منطقی داشته باشه که در این صورت ، اون پردازنده ، تکنولوژی Hyper Thread داره مثل i3 4150 (با 2 هسته ی فیزیکی و 4 هسته ی منطقی (که در هر هسته ی فیزیکی اش ، 2 هسته ی منطقی وجود داره)) . درسته؟

همه پردازنده ها این قابلیت رو ندارند، در بخشی شون هم ذاتا این قابلیت بوده ولی به دلایل تجاری یا فنی فعالش نکردن. اسامی تکنولوژی ها و نحوه پیاده سازی ها هم فرق داره ولی کلا همه شون نوعی از چند نخی شبیه سازی شده در سخت افزار هستند.



الان ، در کدی که من در بالا دادم (کد اول) ، برنامه ام در 2 هسته ی فیزیکی اجرا شد دیگه . هم گفته بودم توان پردازنده رو 50 درصد (از 4 هسته ی فیزیکی که میشه 2 هسته ی فیزیکی) اشغال کرد و هم نسبت به زمانی که کد دو نخ را در یک نخ نوشتم (و بنابراین در یک هسته که 25 درصد از توان پردازنده را اشغال کرده بود) ، دو برابر سریعتر اجرا شد . یعنی در این حالتِ 2 نخی ، زمان اش 25 ثانیه و در حالتِ تک نخی ، زمانش 55 ثانیه طول کشید (حالا حدودا 3 ثانیه این ورتر یا اون ور تر) .
بجز این ، هر چقدر که نخ جدیدی اجرا میکردم ، توان پردازنده ، 25 درصد (در پردازنده ی 4 هسته ایِ i5 4460) افزایش پیدا میکرد و نسبت به تک نخی ، سرعتش بیشتر میشد . مثلا 3 نخ اجرا میکردم ، توان پردازنده ، 75 درصد برای پروسه ام میشد اما همونطور که گفتین ، در 4 نخ ، به 100 نمیرسید و بین 85 تا 95 درصد میشد .

پس ، بنابراین ، وقتی چند نخی کدنویسی میکنیم ، هر نخ ، داخل یک هسته (ی منطقی یا فیزیکی) اجرا میشن دیگه . (چون پردازنده ی من قابلیت Hyper Thread یا همون وجود 2 هسته ی منطقی در هر هسته ی فیزیکی را نداره) . درسته؟
اگه درست نیست ، پس چرا هسته ها بیشتر مشغول و کدها سریعتر انجام میشن؟

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

حالا ببینیم چندین نخ یک پروسه چطور اجرا میشن. سیستم عامل برای اجرای نخ هایی که شما درخواست اجرا شدنشون رو کردید چند تا کار میتونه بکنه :
اول اینکه بیاد نخ ها رو روی یک هسته مجازی اجرا کنه، دائم هم بین نخ ها سوئیچ کنه، به نظر بیاد که نخ ها همزمان اجرا میشن ولی عملا نمیشن.
دوم اینکه بیاد همزمان با نخ ای که روی یک هسته مجازی داره اجرا میشه، نخ همسایه همون هسته مجازی که روی همون هسته فیزیکی قرار داره رو برای اجرای نخ دیگری از برنامه تون بکار ببره.
سوم اینکه پروسه برنامه رو از یک هسته فیزیکی به هسته فیزیکی دیگری جابجا کنه و هسته جدید رو برای اجرای نخ های برنامه بکار ببره.
مادامی که محدودیتی برای سیستم عامل وجود نداشته باشه هر سه تا شون رو میتونه انجام بده ولی به نسبت هر کدوم نسبت به قبلی سربار بیشتری داره و ازشون اجتناب می کنه.
شما وقتی تعداد نخ ها رو بالاتر میبرید سیستم عامل مجبور میشه مدام پروسه شما رو بین هسته های مختلف پاس بده. پردازنده رو مشغول می کنید ولی به قیمت سربار بالا.
ذوق نکنید که هسته های پردازنده خیلی مشغول شدن، دارید بخش عمده ای از توان شون رو هدر میدید. بازدهی برنامه تون بالاتر رفت اما همزمان روی دو هسته فیزیکی اجرا نشدن، بین هسته ها سوئیچ صورت گرفته.



آها ، یعنی بسته به معماری پردازنده هم میتونه داشته باشه؟
یعنی الان ممکنه یکی این کد بالا (اولی) را در پردازنده ی چند هسته ای اجرا کنه اما در دو هسته اش اجرا نشه؟

بله، ممکنه، اینجا محدودیت های معماری پردازنده مهمه و اینکه سیستم عامل از چه قابلیتی در چه پردازنده ای پشتیبانی بکنه، NET. اینجا دخالتی در محدودیت ایجاد شده نداره.



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

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



بله ، خیلی ممنون این ها رو گفته بودین .
البته ، این تداخل که میگین ، بخاطر این نیست که دو تا هسته ی منطقی وقتی در یک هسته ی فیزیکی وجود دارن ، از حافظه ی مشترکی استفاده میکنند؟ یا اینکه از گذرگاه داده ای مشترکی استفاده میکنند؟

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



اگه آره ، اون حافظه ، دقیقا چه حافظه ای هست؟ حافظه ی رجیساری در دو هسته ی منطقی ای که در یک هسته ی فیزیکی وجود دارند ، مشترک هست یا حافظه ی کش l1 یا کش l2 یا l3 ؟

به معماری اون پردازنده خاصی بستگی داره، اصلا حالت کلی و عمومی نداره که حتی تعداد حافظه Cache ها تعداد ثابتی باشه، چه برسه به اینکه کدومها مشترک باشن و کدوم ها نباشن.



و اینکه حافظه ی رجیستری ، حافظه ی اصلی و مهم توی پردازنده هست دیگه . درسته؟

همچین برداشتی نمی کنم چون در معماری پردازنده حافظه غیر مهمی که نداریم اما رجیستر ها جزو موارد اساسی پردازنده ها است.



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

نه. یادتون نگهدارید که نخ، متد، پروسه، فایل و ... جزو مفاهیم سیستم عامل هستند، مجددا یادآوری کنم که پردازنده شناختی از اینها نداره، چه برسه به اینکه بخشی برای نگهداریشون داشته باشه.
اون چیزی که شما میگید تحت عنوان PCB یا Process Control Block مربوط به سیستم عامل ئه، در رجیستر های پردازنده نگهداری نمیشه.
حافظه رجیستر ها خیلی کوچیکتر و محدودتر از این حرف ها است و برای اجرای یک فرمان طراحی شده، نه یک نخ.



بله ، گفته بودید .
اما همونطور که گفته بودید ، معمولا (نه همیشه) میسنجه که ببینه میزان سربارش میصرفه تا سوئیچ کنه یا نه و بعد سوئیچ میکنه به نخ دیگه .

سربار برای سوئیچ رو میسنجه تا ببینه چه نخی چه زمانی روی چه هسته مجازی ای اجرا بشه در مقابل پاسخگویی بهتر سربار کمنری داره، وگرنه همیشه نخ ای هست که بعد نخ شما در نوبت اجرا باشه.
سیستم عامل هر کاری بکنه یک سربار ای داره، هیچ عملیاتی بدون سربار نیست.
سایر برنامه ها در صف انتظار که نمیتونن همینطور بمونن. اونها هم مثل برنامه شما درخواست اجرا دارن.



من دقیق متوجه نشدم .
الان ، نظرتون اینه که کدهای با اونکه 50 درصد از توان (یه پردازنده ی 4 هسته ای) را گرفتن ، اما دارن توی یه هسته اجرا میشن؟
اگه منظورتون اینه ، پس چرا زمان اجراشون هم نسبت به هم (قبلا توضیح دادم) ، تقریبا 2 برابر فرق کرده؟

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



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

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



قطعا اگه این کد اول را توی Parallel بنویسیم و توی پردازنده ی چند هسته ای (یا HyperThread) هم اجرا کنیم ، زمان اجراش از حالتی که من کد اول را در دو نخ نوشتم ، بیشتر نمیشه .

باز از روی قضاوت تون حکم صادر کردید ها.

151023



using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private ListBox _listBox;
private Button _button;
private long n1;
private long n2;
private long n3;
private long MaxValue;
private const int ThreadCount = 16;

private void Form1_Load(object sender, EventArgs e)
{
_button = new Button { Parent = this, Text = "Start", Bounds = new Rectangle(ClientSize.Width - 120, 10, 100, 30) };
_listBox = new ListBox { Parent = this, Dock = DockStyle.Fill };
_button.BringToFront();
_button.Click += button_Click;
}

private void button_Click(object sender, EventArgs e)
{
_button.Enabled = false;
_listBox.Items.Add("Please wait...");
Application.DoEvents();
var stopwatch = new Stopwatch();
stopwatch.Start();
var n = 0L;
for (var i = 0L; i < 10000; i++)
{
var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
stopwatch.Stop();
MaxValue = ThreadCount * 20 * (int)(1000 / stopwatch.Elapsed.TotalSeconds);
stopwatch.Reset();
//n1 = 0;
//stopwatch.Start();
//SingleThreadProc();
//stopwatch.Stop();
//_listBox.Items.Add($"Single thread: {stopwatch.ElapsedMilliseconds:N0}ms Counter: {n1:N0}");
//Application.DoEvents();
//stopwatch.Reset();
n2 = 0;
stopwatch.Start();
var threads = new Thread[ThreadCount];
for (var i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(MultiThreadProc);
threads[i].Start();
}
for (var i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
stopwatch.Stop();
var e1 = stopwatch.ElapsedMilliseconds;
_listBox.Items.Add($"{ThreadCount} threads: {e1:N0}ms Counter: {n2:N0}");
Application.DoEvents();
stopwatch.Reset();
n3 = 0;
stopwatch.Start();
Parallel.For(0, ThreadCount, ActionProc);
stopwatch.Stop();
var e2 = stopwatch.ElapsedMilliseconds;
var factor = Math.Round(100.0 * (e1 - e2) / e1);
_listBox.Items.Add($"{ThreadCount} threads (Parallel): {e2:N0}ms Counter: {n3:N0} ({factor}% faster)");
_listBox.Items.Add("");
_button.Enabled = true;
}

private void SingleThreadProc()
{
var maxValue = (MaxValue / ThreadCount) * ThreadCount;
var n = 0L;
for (var i = 0L; i < maxValue; i++)
{
var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n1, n);
}

private void MultiThreadProc()
{
var maxValue = MaxValue / ThreadCount;
var n = 0L;
for (var i = 0L; i < maxValue; i++)
{
var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n2, n);
}

private void ActionProc(int num)
{
var maxValue = MaxValue / ThreadCount;
var n = 0L;
for (var i = 0L; i < maxValue; i++)
{
var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n3, n);
}
}

mr.sirwan
دوشنبه 04 آذر 1398, 22:38 عصر
@the king
دوست عزیز، قشنگیه خود این مبحث به کنار، شما هم داری خیلی جذابتر توضیح میدی، از اطلاعاتی که داری با ما به اشتراک میذاری خیلی سپاسگزارم، معلومه روی این مباحث کاملا تسلط دارین و از اون مهمتر صبر و حوصله ی ستودنیتون توی توضیح دادن هست، شخصا سعی میکنم تمامی پستهاتون رو دنبال کنم و با دقت گفته هاتون رو مطالعه میکنم

بازم تشکر

pe32_64
دوشنبه 04 آذر 1398, 22:43 عصر
دوست عزیز
SajjadKhati (https://barnamenevis.org/member.php?363659-SajjadKhati)
نخ یا thread پایین ترین سطح api در سیستم عامل رو داره .شما نباید مستقیم ازش در برنامه تون استفاده کنید.
مثال هاتون بسیار ساده ست و هیچ اطلاعات اشتراکی نداره . برای همین مشکلات فراوان استفاده مستقیم از multi-threading خودشون رو نشون ندادن.
در محیط net. شما api های بهتری رو داری با سطح abstraction بالا تر و قابلیت استفاده ساده تر.مثل Task Parallel Library که خودش مجموعه ای از api های مفید هستش و به همین منظور ساخته شده .مانند :
Task-based Asynchronous Programming
Data Parallelism
Dataflow

SajjadKhati
دوشنبه 04 آذر 1398, 22:45 عصر
استاد ، من همین کد (کد اول در پست اول) را در Parallel اجرا کردم ، زمان اجراش ، دقیقا مثل همون کد اول ، 24 ثانیه طول کشید (کد اولی هم که گفته بودم 25 ثانیه ، در واقع 24 ثانیه بود . حالا چون بصورت چشمی ، خودم اندازه گیریِ حدودی میکنم ، مهم نیست . فقط کلیات برام مهم هه نه اندازه گیریِ دقیقِ زمان) :



private void NewThreadMethod_1()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("NewThreadMethod_1 loop finished");
}


private void NewThreadMethod_2()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("NewThreadMethod_2 loop finished");
}


private void TransparentControl5_Click(object sender, EventArgs e)
{
Action[] actions = new Action[] { new Action(this.NewThreadMethod_1), new Action(this.NewThreadMethod_2) };
Parallel.Invoke(actions);
}


این هم مثل اون ، 50 درصد از توان پردازنده ام ، یعنی 2 هسته ی فیزیکی (که همون 2 هسته ی منطقی اش هم میشه) را اشغال کرد .

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

اما شما هم این کدی که من در پست 4 دادم (همینی که نقل قول کردم) را بررسی میکنید؟
پس چرا این کد را که با parallel نوشتم ، هم از لحاظ زمان اجرا و هم از لحاظ آمار درگیر کردنِ توانِ پردازنده (که در task manager میده) ، با کد اول در پست اول (که با thread کار کرده بودم) ، دقیقا یکی هست؟

شما میگید که وقتی آمار میده که 50 درصد از توان پردازنده را داره صرف پروسه ی من میکنه ، با این حال ، فقط یک هسته همزمان داره پروسه و نخ های پروسه ی من را پردازش میکنه (اما در حال سوئیچ مداوم هست) ؟
پس یعنی دارید میگید یک هسته داره درگیرش میشه دیگه؟
اگه یک هسته داره درگیرش میشه ، پس چرا task manager ، آمار میده که دو هسته ام داره اشغال میشه؟ متوجه ی منظورم شدید؟ منظورم اینه که یک هسته (حتی با وجود سوئیچ کردن) ، باز 25 درصد توان پردازنده ام هست . پس چرا میگه 50 درصد؟
و مهمتر از اون ، چرا سرعت انجام کارها 2 برابر شده؟ خوب ، وقتی در یک هسته انجام بشه ، نباید سرعت انجام کدها در یک نخ و دو نخ فرقی داشته باشن . پس در این صورت باید کد اولم در پست اول با کد دوم ام در پست اول ، زمان اجراشون یکی باشن . اما کد اولی ، 2 برابر سریعتر انجام میشه .

از نظرات بقیه ی دوستان هم خیلی ممنونم.

pe32_64
دوشنبه 04 آذر 1398, 22:55 عصر
سلامی مجدد
...
پس چرا این کد را که با parallel نوشتم ، هم از لحاظ زمان اجرا و هم از لحاظ آمار درگیر کردنِ توانِ پردازنده (که در task manager میده) ، با کد اول در پست اول (که با thread کار کرده بودم) ، دقیقا یکی هست؟


parallel از thread استفاده میکنه .در اصل همه concurrency api ها از ترد استفاده میکنند.

SajjadKhati
دوشنبه 04 آذر 1398, 23:04 عصر
parallel از thread استفاده میکنه .در اصل همه concurrency api ها از ترد استفاده میکنند.

ممنون
بله میدونم
منتها Parallel که کدها را در هسته ها بصورت همزمان اجرا میکنه ، نمیدونم حالا Thread هم این کار را میکنه یا نه (میخوام اینو بدونم)
شواهد من نشون میده Thread هم کدها را بصورت همزمان اجرا میکنه (که به استاد ارائه دادم) ولی استاد انگار میگه نمیکنه .
خودمم گیج شدم چی به چیه .

pe32_64
دوشنبه 04 آذر 1398, 23:29 عصر
ممنون
بله میدونم
منتها Parallel که کدها را در هسته ها بصورت همزمان اجرا میکنه ، نمیدونم حالا Thread هم این کار را میکنه یا نه (میخوام اینو بدونم)
شواهد من نشون میده Thread هم کدها را بصورت همزمان اجرا میکنه (که به استاد ارائه دادم) ولی استاد انگار میگه نمیکنه .
خودمم گیج شدم چی به چیه .
خوب وقتی میدونین دیگه سوال کردنش برا چیه ؟!
تمام کار ها اخرش ختم میشه به
Thread ، تمام ! خودتون رو گیچ نکنید.
****
کار اصلی اجرای کد در سیستم عامل با Thread هستش.حتی وقتی یک فایل Exe رو باز می کنید براش یک ترد ساخته میشه تا کد برنامه درونش اجرا شه .
Parallel هم 2 تا ترد میسازه و کد شما رو بش تحویل میده برا اجرا .بعد هم نتیجه کارشون رو میگیره و پس میفرسته. این البته ساده شدست ولی اصول کلیش همین هستش.

SajjadKhati
سه شنبه 05 آذر 1398, 14:56 عصر
سلامی مجدد
استاد ، من کدتون را بصورت زیر تغییر دادم ، حتی نتیجه ی معکوس هم داد :



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;


namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}


private ListBox _listBox;
private Button _button;
private long n1;
private long n2;
private long n3;
private long MaxValue;
private const int ThreadCount = 16;


private void Form1_Load(object sender, EventArgs e)
{
_button = new Button { Parent = this, Text = "Start", Bounds = new Rectangle(ClientSize.Width - 120, 10, 100, 30) };
_listBox = new ListBox { Parent = this, Dock = DockStyle.Fill };
_button.BringToFront();
_button.Click += button_Click;
}


private void button_Click(object sender, EventArgs e)
{
_button.Enabled = false;
_listBox.Items.Add("Please wait...");
Application.DoEvents();
var stopwatch = new Stopwatch();
stopwatch.Start();
var n = 0L;
for (var i = 0L; i < 10000000000; i++)
{
//var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
stopwatch.Stop();
MaxValue = ThreadCount * 20 * (int)(1000 / stopwatch.Elapsed.TotalSeconds);
stopwatch.Reset();
//n1 = 0;
//stopwatch.Start();
//SingleThreadProc();
//stopwatch.Stop();
//_listBox.Items.Add($"Single thread: {stopwatch.ElapsedMilliseconds:N0}ms Counter: {n1:N0}");
//Application.DoEvents();
//stopwatch.Reset();
n2 = 0;
stopwatch.Start();
var threads = new Thread[ThreadCount];
for (var i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(MultiThreadProc);
threads[i].Start();
}
for (var i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
stopwatch.Stop();
var e1 = stopwatch.ElapsedMilliseconds;
_listBox.Items.Add($"{ThreadCount} threads: {e1:N0}ms Counter: {n2:N0}");
Application.DoEvents();
stopwatch.Reset();
n3 = 0;
stopwatch.Start();
Parallel.For(0, ThreadCount, ActionProc);
stopwatch.Stop();
var e2 = stopwatch.ElapsedMilliseconds;
var factor = Math.Round(100.0 * (e1 - e2) / e1);
_listBox.Items.Add($"{ThreadCount} threads (Parallel): {e2:N0}ms Counter: {n3:N0} ({factor}% faster)");
_listBox.Items.Add("");
_button.Enabled = true;
}


private void SingleThreadProc()
{
var maxValue = (MaxValue / ThreadCount) * ThreadCount;
var n = 0L;
for (var i = 0L; i < maxValue; i++)
{
var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n1, n);
}


private void MultiThreadProc()
{
var maxValue = MaxValue / ThreadCount;
var n = 0L;
for (var i = 0L; i < 10000000000; i++)
{
//var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n2, n);
}


private void ActionProc(int num)
{
var maxValue = MaxValue / ThreadCount;
var n = 0L;
for (var i = 0L; i < 10000000000; i++)
{
//var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n3, n);
}


}
}





https://barnamenevis.org/attachment.php?attachmentid=151025&stc=1

کد زیر در حلقه ها را غیر فعال کردم :



var x = DateTime.Now.Year - Environment.TickCount;


و همچنین تعداد تکرار حلقه ها را 10000000000 بار کردم .

بعد اینکه حتی اگه بهتر هم کار کنه ، معمولا زیر 10 درصد هست . اون هم در جایی که متغییر سراسری هم در حلقه ها (درون نخ های مختلف) استفاده نمیشه که نقطه ی بحرانی پدید بیاد . بنابراین این نشون دهنده ی این نیست که این اختلاف شون بخاطر اینه که کلاس Thread از چند هسته ای (بصورت همزمان) استفاده نمیکنه اما کلاس Parallel از چند هسته بصورت همزمان استفاده نمیکنه . چون در الگوریتمی که نقطه ی بحرانی نداره (یا خیلی کم داره و در قسمت اصلی اش حدقل نقطه ی بحرانی نداره) ، استفاده از 4 هسته ی فیزیکی ، حداقل باید کارایی را 90 درصد بالاتر ببره (نسبت به تک هسته ای) اما در بهترین حالت ، کلاس Parallel فقط 10 درصد سرعت بیشتری داره که به نظر میرسه بخاطر ساختار بهتر کدهایی که مایکروسافت براش در نظر گرفت باشه . نه اینکه کلاس Parallel از چند هسته بصورت همزمان بتونه استفاده کنه و کلاس Thread نتونه استفاده کنه .
البته این باز هم نظر من هه . مستند نیست . ممکنه بخاطر معماری پردازنده ی من باشه . ممکنه هم نباشه . نمیدونم .

اگه پست 4 ام رو هم جواب میدادین ، خیلی ممنون میشدم .
خیلی ممنون که تا اینجا راهنمایی کردین .

the king
سه شنبه 05 آذر 1398, 16:10 عصر
اول پروژه ای رو که نوشتم پیوست کنم تا بعد به مسائل مربوطه بپردازیم :

151027

بخاطر محدودیت های ماشین مجازی NET. نمیشه خیلی بصورت دقیق روی اجرای بازدهی نخ یا هسته ها متمرکز شد ولی این برنامه که نوشتم حداقل میتونه کارکرد کلی رو نشون بده :

151028

the king
سه شنبه 05 آذر 1398, 16:26 عصر
@the king
دوست عزیز، قشنگیه خود این مبحث به کنار، شما هم داری خیلی جذابتر توضیح میدی، از اطلاعاتی که داری با ما به اشتراک میذاری خیلی سپاسگزارم، معلومه روی این مباحث کاملا تسلط دارین و از اون مهمتر صبر و حوصله ی ستودنیتون توی توضیح دادن هست، شخصا سعی میکنم تمامی پستهاتون رو دنبال کنم و با دقت گفته هاتون رو مطالعه میکنم

بازم تشکر

نظر لطف شما است. خیلی ممنونم.


استاد ، من همین کد (کد اول در پست اول) را در Parallel اجرا کردم ، زمان اجراش ، دقیقا مثل همون کد اول ، 24 ثانیه طول کشید (کد اولی هم که گفته بودم 25 ثانیه ، در واقع 24 ثانیه بود . حالا چون بصورت چشمی ، خودم اندازه گیریِ حدودی میکنم ، مهم نیست . فقط کلیات برام مهم هه نه اندازه گیریِ دقیقِ زمان) :



private void NewThreadMethod_1()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("NewThreadMethod_1 loop finished");
}


private void NewThreadMethod_2()
{
for (long counter = 0; counter < 10000000000; counter++)
{
}


MessageBox.Show("NewThreadMethod_2 loop finished");
}


private void TransparentControl5_Click(object sender, EventArgs e)
{
Action[] actions = new Action[] { new Action(this.NewThreadMethod_1), new Action(this.NewThreadMethod_2) };
Parallel.Invoke(actions);
}


این هم مثل اون ، 50 درصد از توان پردازنده ام ، یعنی 2 هسته ی فیزیکی (که همون 2 هسته ی منطقی اش هم میشه) را اشغال کرد .

چند تا فرض اولیه دارید که درست نیستند. اول اینکه پردازنده مشغول پروسه برنامه شما بشه به معنی این نیست که داره با همون توان کد های نخ شما رو اجرا می کنه. فراموش نکنید که برنامه شما در ماشین مجازی قرار داره، بخش قابل توجهی از کاری که پردازنده برای پروسه شما انجام میده صرف تبادل بین ماشین مجازی و حقیقی میشه که اگر این بود سرعت اجرای کد های #C به حد متعارف C++ Native میرسید.
این رو از این بابت عرض می کنم که 50 درصد توان پردازنده صرف اجرای کد شما نشده، 50 درصد توانش گرفته شده تا فرضا کد شما را با دو برابر سرعتی که یک نخ برنامه شما رو اجرا می کرد اجرا کنه.
نخ های شما از 50 درصد توان پردازنده استفاده نکردن، ولی سیستم عامل حداکثر میزانی که برای یک برنامه چند نخی ارائه میکنه تحویل داده.
از طرف دیگه Task Manager اجرای همگام نخ ها رو به شما نشون نمیده. توان کلی صرف شده توسط پردازنده رو نشون میده، اونم با یک آمار غیر دقیق.
Task Manager بهتون نمیگه که چقدر از توان پردازنده رو در حین سوئیچ کردن ها هدر میدید، شما اونها رو جزو کارایی کدتون حساب می کنید چون با اجرای یک نخی پردازنده مقایسه اش می کنید که انگار نخ یکنواخت اجرا میشه.
در حالی که اگر سرعت اجرای نخ رو با سرعت بالا بررسی می کردیم دائم اجرا متوقف شده بود، این موارد ریز رو سیستم عامل نشون نمیده.

the king
سه شنبه 05 آذر 1398, 17:32 عصر
سلامی مجدد
استاد ، من کدتون را بصورت زیر تغییر دادم ، حتی نتیجه ی معکوس هم داد :



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;


namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}


private ListBox _listBox;
private Button _button;
private long n1;
private long n2;
private long n3;
private long MaxValue;
private const int ThreadCount = 16;


private void Form1_Load(object sender, EventArgs e)
{
_button = new Button { Parent = this, Text = "Start", Bounds = new Rectangle(ClientSize.Width - 120, 10, 100, 30) };
_listBox = new ListBox { Parent = this, Dock = DockStyle.Fill };
_button.BringToFront();
_button.Click += button_Click;
}


private void button_Click(object sender, EventArgs e)
{
_button.Enabled = false;
_listBox.Items.Add("Please wait...");
Application.DoEvents();
var stopwatch = new Stopwatch();
stopwatch.Start();
var n = 0L;
for (var i = 0L; i < 10000000000; i++)
{
//var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
stopwatch.Stop();
MaxValue = ThreadCount * 20 * (int)(1000 / stopwatch.Elapsed.TotalSeconds);
stopwatch.Reset();
//n1 = 0;
//stopwatch.Start();
//SingleThreadProc();
//stopwatch.Stop();
//_listBox.Items.Add($"Single thread: {stopwatch.ElapsedMilliseconds:N0}ms Counter: {n1:N0}");
//Application.DoEvents();
//stopwatch.Reset();
n2 = 0;
stopwatch.Start();
var threads = new Thread[ThreadCount];
for (var i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(MultiThreadProc);
threads[i].Start();
}
for (var i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
stopwatch.Stop();
var e1 = stopwatch.ElapsedMilliseconds;
_listBox.Items.Add($"{ThreadCount} threads: {e1:N0}ms Counter: {n2:N0}");
Application.DoEvents();
stopwatch.Reset();
n3 = 0;
stopwatch.Start();
Parallel.For(0, ThreadCount, ActionProc);
stopwatch.Stop();
var e2 = stopwatch.ElapsedMilliseconds;
var factor = Math.Round(100.0 * (e1 - e2) / e1);
_listBox.Items.Add($"{ThreadCount} threads (Parallel): {e2:N0}ms Counter: {n3:N0} ({factor}% faster)");
_listBox.Items.Add("");
_button.Enabled = true;
}


private void SingleThreadProc()
{
var maxValue = (MaxValue / ThreadCount) * ThreadCount;
var n = 0L;
for (var i = 0L; i < maxValue; i++)
{
var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n1, n);
}


private void MultiThreadProc()
{
var maxValue = MaxValue / ThreadCount;
var n = 0L;
for (var i = 0L; i < 10000000000; i++)
{
//var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n2, n);
}


private void ActionProc(int num)
{
var maxValue = MaxValue / ThreadCount;
var n = 0L;
for (var i = 0L; i < 10000000000; i++)
{
//var x = DateTime.Now.Year - Environment.TickCount;
n++;
}
Interlocked.Add(ref n3, n);
}


}
}





https://barnamenevis.org/attachment.php?attachmentid=151025&stc=1

کد زیر در حلقه ها را غیر فعال کردم :



var x = DateTime.Now.Year - Environment.TickCount;


و همچنین تعداد تکرار حلقه ها را 10000000000 بار کردم .

بعد اینکه حتی اگه بهتر هم کار کنه ، معمولا زیر 10 درصد هست . اون هم در جایی که متغییر سراسری هم در حلقه ها (درون نخ های مختلف) استفاده نمیشه که نقطه ی بحرانی پدید بیاد . بنابراین این نشون دهنده ی این نیست که این اختلاف شون بخاطر اینه که کلاس Thread از چند هسته ای (بصورت همزمان) استفاده نمیکنه اما کلاس Parallel از چند هسته بصورت همزمان استفاده نمیکنه . چون در الگوریتمی که نقطه ی بحرانی نداره (یا خیلی کم داره و در قسمت اصلی اش حدقل نقطه ی بحرانی نداره) ، استفاده از 4 هسته ی فیزیکی ، حداقل باید کارایی را 90 درصد بالاتر ببره (نسبت به تک هسته ای) اما در بهترین حالت ، کلاس Parallel فقط 10 درصد سرعت بیشتری داره که به نظر میرسه بخاطر ساختار بهتر کدهایی که مایکروسافت براش در نظر گرفت باشه . نه اینکه کلاس Parallel از چند هسته بصورت همزمان بتونه استفاده کنه و کلاس Thread نتونه استفاده کنه .
البته این باز هم نظر من هه . مستند نیست . ممکنه بخاطر معماری پردازنده ی من باشه . ممکنه هم نباشه . نمیدونم .

اگه پست 4 ام رو هم جواب میدادین ، خیلی ممنون میشدم .
خیلی ممنون که تا اینجا راهنمایی کردین .

قدم به قدم بریم جلو. اینکه همه الگوریتم ها و همه روتین ها برای اجرای موازی مناسب نباشن که بدیهی است، اصلا توقع نداریم که هر الگوریتمی با اجرای موازی سرعت اجراش افزایش پیدا کنه.
از طرف دیگه میدونیم که برای دسترسی به اشیاء Static سربار بیشتری برای روتین های موازی تحمیل میشه.
در ضمن اگر ساختن Thread به تنهایی باعث میشه که چندین هسته همزمان بکار گرفته بشن باید این مساله همیشه خودش رو نشون بده :
151029
پس چطور هر ترکیبی از چهار CPU ابتدایی رو انتخاب کنم همچنان دو نخ همگام اجرا میشن؟ شما که مدعی هستید اینها از توان هسته های مجزا استفاده میکنند، پس چرا وقتی یک نخ مشغول اجرا است نخ دیگه در حال اجرا نیست؟
از طرف دیگه چرا باید کارایی 90 درصد بالاتر بره؟ با چه فرمولی همچین محاسبه ای کردید؟ در پردازش موازی دو برابر شدن تعداد هسته ها به دو برابر شدن کارایی ختم نمیشه.
معیاری دقیقی هم نداریم که نشون بده چقدر از توان پردازنده در این بین هدر رفته اما حداقل میتونیم نشون بدیم که اولا اجرای همگامی هست که در Task Manager نشون داده نمیشه و ثانیا چیزی که تحت عنوان توان پردازنده صرف اجرای پروسه شده صرفا بخشی اش برای اجرای کد شما است. اینکه با اجرای تعداد بیشتر نخ توان بیشتری میگیرید و کارایی افزایش پیدا میکنه واقعیت داره ولی نه بخاطر اینکه چند هسته مستقل همزمان مشغول اجرای کد میشن.
به چه مدرکی ؟

یک نخ رو به تنهایی اجرا می کنیم، کارکرد نزدیک به 100 درصد (98 درصد) اجرای آزمایشی ابتدای برنامه رو داره. حالا اگر تعداد نخ ها رو 4 برابر کنیم بنا به گفته شما نخ ها میتوانند روی هسته های مجزا اجرا بشن، پس باید کارایی حدودا چهار برابر بشه،


یعنی 392 درصد. ولی صرفا از 98 درصد به 269 درصد رسید. نه دو برابر شد و نه چهار برابر. حتی اگر دو برابر میشد فرض رو بر این میگرفتیم که دو هسته روی یک هسته فیزیکی قرار دارند و نمی توانند همزمان کد مشابه اجرا کنند.
حالا بر چه اساسی قبول کنیم که توان اجرای یک هسته اون 98 درصد بوده؟ چرا اجرای چند هسته ای منجر به چیزی نشد که انتظار داشتیم؟
در حقیقت حتی در همون اجرای یک نخی هم یک هسته تمامی توانش رو صرف اجرای کد نکرده و ما فقط با تعداد درخواست بیشتر سیستم عامل رو وادار به پاسخگویی بیشتر میکنیم. توان هسته هدر رفته ولی بخش عمده ای بخاطر سوئیچ های پی در پی هدر رفته.



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


اگر بخواهیم نظر شما رو بپذیریم که اندکی کارایی بهتر Parallel بخاطر اجرای موازی در چندین هسته نبوده و نخ سازی هم منجر به اجرای چند هسته ای میشه با این مشکل مواجه میشیم که مدرکی نداریم که نشون بده نخ سازی منجر به اجرای موازی در چند هسته فیزیکی شده.
وقتی سیستم عامل رو وادار میکنیم سوئیچ کردن بین CPU ها رو محدود کنه متوجه این قضیه میشیم که در واقع این سوئیچ کردن سریع بین CPU ها بوده که ظاهر اجرای موازی رو ایجاد کرده، این همون اجرای همگام ئه، نه موازی. CPU های بیشتری رو درگیر می کنه ولی نه این معنی که بازدهی به همون اندازه است که اجرای موازی داشته، به اندازه اجرای همگام کارایی داره، چون واقعا موازی نیست.

SajjadKhati
سه شنبه 05 آذر 1398, 18:02 عصر
اول پروژه ای رو که نوشتم پیوست کنم تا بعد به مسائل مربوطه بپردازیم :

151027

بخاطر محدودیت های ماشین مجازی NET. نمیشه خیلی بصورت دقیق روی اجرای بازدهی نخ یا هسته ها متمرکز شد ولی این برنامه که نوشتم حداقل میتونه کارکرد کلی رو نشون بده :

151028

خیلی ممنون استاد . زحمت کشیدید . :قلب:
الان این برنامه رو نوشتید تا هر وقت دکمه ی New Thread را میزنیم ، هر بار به مدت 20 ثانیه ، نخ جدیدی ساخته و پردازش میشه و وقتی مثلا دو بار این دکمه رو زدیم ، 2 نخ ساخته میشه و نشون بده عملکرد هر هسته و سوئیچ بین این نخ ها در هسته ها ، چجوری هه؟
الان یعنی با این عکسی که گذاشتید ، اولا 2 نخ ساختید که مدام بین دو هسته ی منطقیِ پردازنده تون ، در حال سوئیچ کردن هست اما همزمان فقط در یک هسته ی منطقی در حال اجرا شدن هست (چون نمودار سبز رنگ ، در یک لحظه ، فقط در یک قسمت وجود داره) . درست میگم؟

اما من همین برنامه تون را در کامپیوتر خودم اجرا کردم و نتیجه جور دیگه ای هست :


https://barnamenevis.org/attachment.php?attachmentid=151030&stc=1


https://barnamenevis.org/attachment.php?attachmentid=151031&stc=1




https://barnamenevis.org/attachment.php?attachmentid=151032&stc=1



اگه درکی که من از برنامه تون کردم ، درست باشه ، واسه ی من وقتی 3 نخ را اجرا میکنم ، همزمان 3 هسته ی فیزیکی (که برای من برابر با 3 هسته ی منطقی هم هست) را درگیر میکنه (یعنی 75 درصد از پردازنده رو پروسه ام اشغال میکنه حتی طبق آمار برنامه ی شما که عکسش مشخص هست و برخلاف عکسی که برای شما هست ، هست) .
وقتی 2 نخ ایجاد کنم ، همزمان 2 هسته و اگه 4 نخ ، همزمان همه ی هسته ها را درگیر میکنه .

میگم استاد ، شاید بخاطر این باشه که شما در قسمت پایینی برنامه تون ، فقط دو هسته (که نمیدونم فیزیکی هستن یا نه) را فقط تیک میزنید . همه ی هسته هاتون را تیک میزنید ، نتیجه شو ببینید چی میشه؟

الان ، این به معماری پردازنده ی من فقط مربوط میشه؟
اگه نه ، پس واسه ی شما چرا مثل من نیست و در یک لحظه ، فقط یک هسته ی منطقی را اشغال میکنه؟
میتونم مدل دقیق پردازنده تون را بدونم؟ (اگه دوست دارین بگین)







چند تا فرض اولیه دارید که درست نیستند. اول اینکه پردازنده مشغول پروسه برنامه شما بشه به معنی این نیست که داره با همون توان کد های نخ شما رو اجرا می کنه. فراموش نکنید که برنامه شما در ماشین مجازی قرار داره، بخش قابل توجهی از کاری که پردازنده برای پروسه شما انجام میده صرف تبادل بین ماشین مجازی و حقیقی میشه که اگر این بود سرعت اجرای کد های #C به حد متعارف C++‎‎‎‎‎‎‎ Native میرسید.


که این کدهای clr یا ماشین مجازی را در Task Manager ، در سربرگ Performance ، بصورت Kernel Time مشخص میشه (قبلا گفته بودید) . درسته؟




این رو از این بابت عرض می کنم که 50 درصد توان پردازنده صرف اجرای کد شما نشده، 50 درصد توانش گرفته شده تا فرضا کد شما را با دو برابر سرعتی که یک نخ برنامه شما رو اجرا می کرد اجرا کنه.
نخ های شما از 50 درصد توان پردازنده استفاده نکردن، ولی سیستم عامل حداکثر میزانی که برای یک برنامه چند نخی ارائه میکنه تحویل داده.


بله میدونم . ممنون



از طرف دیگه Task Manager اجرای همگام نخ ها رو به شما نشون نمیده. توان کلی صرف شده توسط پردازنده رو نشون میده، اونم با یک آمار غیر دقیق.


منظورتون اینه که Task Manager ، مثل عکسی که از برنامه تون فرستادید ، نشون نمیده که همزمان ، فقط یک هسته داره روی پروسه مون پردازش انجام میده؟
اگه آره ، خوب توی قسمت سربرگ Details میگه دیگه . مثلا میگه 25 درصد از توان پردازنده ، صرف پروسه مون داره میشه (حالا کدهای clr و اینها که گفتید ، میدونم و بماند) که این 25 درصد ، در 4 هسته ، میشه یک هسته بصورت همزمان دیگه .
یا مثلا میگه 50 درصد که میشه 2 هسته بصورت همزمان و ... . درسته دیگه؟



Task Manager بهتون نمیگه که چقدر از توان پردازنده رو در حین سوئیچ کردن ها هدر میدید، شما اونها رو جزو کارایی کدتون حساب می کنید چون با اجرای یک نخی پردازنده مقایسه اش می کنید که انگار نخ یکنواخت اجرا میشه.
در حالی که اگر سرعت اجرای نخ رو با سرعت بالا بررسی می کردیم دائم اجرا متوقف شده بود، این موارد ریز رو سیستم عامل نشون نمیده.


بله ، خیلی خوب میشد اگه یه برنامه شبیه همچین چیزی که شما نوشتید رو Task Manager داشت . خیلی دقیق تر میشد به نکات ریز پی برد .
اما همونطور که قبلا هم گفته بودید ، زمان سوئیچ کردن و هدر رفتن و سربار یک هسته ، برای ما و سیستم عامل ، مهم نیست چون به هر حال در اون زمان ، از دید سیستم عامل ، اون هسته در حالت اشغال قرار داره . چه در حال سوئیچ روی نخ ای باشه و چه منتظر رسیدن اطلاعات از کش یا رم باشه .


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


سئوال بعدی اینکه چرا پروسه ی سی شارپ مون ، وقتی خودمون اصلا نخ ای درست نمیکنیم ، در برنامه ی Resource Monitor در قسمت Threads اش میگه بیش از 1 نخ داره؟ (معمولا بین 8 تا 15 نخ میگه داره) . اینها ، نخ هایی هست که خود clr ایجاد میکنه؟

خیلی ممنون استاد از جواب تون :قلب:

the king
سه شنبه 05 آذر 1398, 20:24 عصر
خیلی ممنون استاد . زحمت کشیدید . :قلب:
الان این برنامه رو نوشتید تا هر وقت دکمه ی New Thread را میزنیم ، هر بار به مدت 20 ثانیه ، نخ جدیدی ساخته و پردازش میشه و وقتی مثلا دو بار این دکمه رو زدیم ، 2 نخ ساخته میشه و نشون بده عملکرد هر هسته و سوئیچ بین این نخ ها در هسته ها ، چجوری هه؟
الان یعنی با این عکسی که گذاشتید ، اولا 2 نخ ساختید که مدام بین دو هسته ی منطقیِ پردازنده تون ، در حال سوئیچ کردن هست اما همزمان فقط در یک هسته ی منطقی در حال اجرا شدن هست (چون نمودار سبز رنگ ، در یک لحظه ، فقط در یک قسمت وجود داره) . درست میگم؟

بله. اینکه در یک هسته اجرا شدن رو نمیتونم مطمئن باشم، من که نمیبینم کدوم هسته داره اجراش میکنه که بگم هر دوشون هسته های اجرا کننده شون شماره فلان ئه. چون انتخاب هسته من صرفا یک هسته نیست و دو هسته است.
میتونه بین شون سوئیچ صورت گرفته باشه ولی مشخصه که تا یکی از نخ ها در حال اجرا است نخ دیگه متوقف میشه و اجرای همگام دارن، نه موازی.



اما من همین برنامه تون را در کامپیوتر خودم اجرا کردم و نتیجه جور دیگه ای هست :


https://barnamenevis.org/attachment.php?attachmentid=151032&stc=1

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

وقتی 2 نخ ایجاد کنم ، همزمان 2 هسته و اگه 4 نخ ، همزمان همه ی هسته ها را درگیر میکنه .

بینید من برداشتم از اجرای کد روی سیستم شما چیه. شما چهار انتخاب CPU داشتید که هر چهار تا رو فعال دارید، یعنی سیستم عامل دستش باز ئه که هر زمان اراده کرد بین CPU ها سوئیچ کنه و محدودیتی در این مورد اعمال نشده.
از طرف دیگه نه برنامه من و نه NET. نمیگه که این نخ شما که الان با 100 درصد مشغولی نسبت به چند لحظه قبل قرار داره رو کدوم هسته اجرا میشه. از اون مهمتر اینکه ما نمیدونیم وقتی میگه پردازنده رو 100 درصد مشغول کرده مشغول چه کاری کرده.
آمار تفکیک شده هم به ما نمیده، میگه در کل پردازنده اینقدر زمان صرف اجرای نخ شما کرده، نمیگه فلان هسته اینقدر و بهمان هسته اونقدر. و نمیگه از این زمان چقدرش هدر رفته و چقدرش داشته کد داخل حلقه رو اجرا میکرده.
یک نگاهی به مقادیر انتهایی بندازید، شما سه تا نخ داشتید که در مجموع 2.56 برابر حالت تک نخی آزمایش شده در ابتدای برنامه کارایی نشون دادن. ولی نمیدونیم که تو اون اجرای چند نخی چند بار اجرا متوقف شده و از سر گرفته شده.
اونقدر زمان ها کوچیک و بهم نزدیکه که معلوم نمیشه. فرض کنید، صرفا یک مثاله، که سیستم عامل اومده هر یک سوم میلی ثانیه کدی از نخ رو روی یک هسته اجرا کرده و بعد دو سوم به کار دیگری پرداخته.
ما هم متوجه نمیشیم چون این سوئیچ کردن بین نخ ها و سربار ماشین مجازی همونقدر هست که Task Manager کل زمان هسته رو برای پروسه ما مشغول نشون بده.
حالا اومدیم و دو تا نخ اضافه کردیم، اینبار پردازنده کل میلی ثانیه ها رو بین سه نخ ما سوئیچ بکنه، حالا روی همون یک هسته یا با سوئیچ روی هر هسته دیگری که دلش خواست، مهم نیست.
آیا اگر اجرای این سه نخ همگام باشه کارایی بیشتر از تک نخی نمیشه؟ چرا میشه، با وجود اینکه اجرای موازی نیست کارایی بیشتر میشه چون بجای اینکه یک سوم لحظه کد اجرا کنه و قدری سربار ایجاد کنه سه برابر کد اجرا میکنه و مقدار بیشتری هم سربار ایجاد میکنه.
من زمانی میتونم بپذیرم که اجرای روی سه هسته فیزیکی صورت گرفته باشه که یا این مساله رو بشه نشون داد که هم مثال نقض براش دارم و هم اینکه نمیشه داخل NET. نشونش داد و یا مدرکی داشته باشیم که بجز با اجرای موازی چند هسته ای نمیشه همچین خروجی ای داشت که اونم هنوز ندیدم. من قبول دارم که پردازنده فرضا 75% مشغول برنامه شما باشه یا سه هسته درگیر بشه یا کد سه نخی 256 درصد سرعت تک نخی خروجی بده ولی با چه ملاکی قضاوت کنیم که این اجرای همگام نیست. وقتی شما با سرعت بالا بین سه هسته سوئیج کنید و هر لحظه روی یکی شون کدی اجرا کنید هم همینقدر اون سه تا رو میشه مشغول کرد و هم میشه همینقدر کارایی دریافت کرد. به نظرتون عجیب نیست که کدی که یک نخش اش 100% سرعت داره چرا در اجرای سه نخی روی هسته مجزا باید %86 بشه؟



میگم استاد ، شاید بخاطر این باشه که شما در قسمت پایینی برنامه تون ، فقط دو هسته (که نمیدونم فیزیکی هستن یا نه) را فقط تیک میزنید . همه ی هسته هاتون را تیک میزنید ، نتیجه شو ببینید چی میشه؟

من در چهار حالت مختلف تیک زدم، فرض کنیم دو هسته منطقی در یک هسته فیزیکی در اون حالت ها وجود داشته باشه، اما دیگه هر چهار حالتش که نمیتونه اینطور باشه. در پردازنده چهار هسته ای فیزیکی با هشت هسته منطقی دارم، هر چقدر بخوام گزینشی انتخاب کنم بالاخره از اون چهار حالت حداکثر دو حالت میتونست هسته فیزیکی مستقل نباشه.
وقتی همه هسته ها فعال باشن تک نخی که میشه مثل همون حالت ابتدای برنامه که 100 درصد یا 98 درصد خروجی میده و در حالت دو نخی هم که میشه حدود 83 درصد و 82 درصد شبیه تصاویر شما پیوسته و بدون مکث و به همون نسبت که نخ ها افزایش پیدا میکنند درصد کارایی هر نخ میاد پایینتر. منم دقیقا همین مساله رو شاهدی بر این میگیرم که اجرای موازی نیست. اگر اجرای چند هسته موازی در کار ئه، چرا باید روی سیستم 8 هسته ای بازدهی اجرای 5 نخ همزمان برسه به 58 الی 60 درصد که جمعش 294 درصد ئه. اگر اجرای چند هسته ای باشه در بدترین حالت 4 هسته فیزیکی نباید خروجی بهتر از 294 درصد بدن؟ این سربار بالا از کجا میاد جز اینکه دارن همگام اجرا میشن، نه موازی.



الان ، این به معماری پردازنده ی من فقط مربوط میشه؟

اینکه به معماری پردازنده شما مربوط هست که قطعا بله ولی سیستم عامل و تنظیماتش و درایور و ...ترافیک پروسه ها هم نقش داره.



میتونم مدل دقیق پردازنده تون را بدونم؟ (اگه دوست دارین بگین)

Intel Core i7 4700HQ



که این کدهای clr یا ماشین مجازی را در Task Manager ، در سربرگ Performance ، بصورت Kernel Time مشخص میشه (قبلا گفته بودید) . درسته؟

نه کد های ماشین مجازی که نه. اگر Process.GetCurrentProcess().PrivilegedProcessorTim e رو بررسی کنید می بینید که یک زمان ناچیز ئه و با Process.GetCurrentProcess().UserProcessorTime.ToSt ring() قابل مقایسه نیست.
وقتی نمی تونیم در NET. برنامه مود هسته یا درایو بنویسیم طبعا کد های CLR ای که اجرا می کنیم هم در اون مود نیستند.



منظورتون اینه که Task Manager ، مثل عکسی که از برنامه تون فرستادید ، نشون نمیده که همزمان ، فقط یک هسته داره روی پروسه مون پردازش انجام میده؟

برنامه من هم نشون نمیده. من در مشخصات Thread ام نمی تونم بفهمم کدوم CPU مجازی داره اجراش می کنه، برای همین هم نمیتونم بفهمم چند هسته مشارکت کردن.
صرفا میتونم از سیستم عامل درخواست کنم که لطفا روی فلان CPU مجازی اجرا کن.



اگه آره ، خوب توی قسمت سربرگ Details میگه دیگه . مثلا میگه 25 درصد از توان پردازنده ، صرف پروسه مون داره میشه (حالا کدهای clr و اینها که گفتید ، میدونم و بماند) که این 25 درصد ، در 4 هسته ، میشه یک هسته بصورت همزمان دیگه .
یا مثلا میگه 50 درصد که میشه 2 هسته بصورت همزمان و ... . درسته دیگه؟

دقیقا، میگه درگیر شد، ولی نمیگه موازی درگیر شد یا همگام. به این مساله توجه کنید که شما با دو نخ دو تا هسته رو درگیر می کنید ولی خروجی 2 برابر که نمی گیرید. این اجرا موازیه؟ اگر موازیه و مستقل ئه چرا اینقدر سربار داره؟



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

انجمن #C ئه ها، نه سخت افزار. اینجا هم من کاربر ساده ام، مباحث نامربوط بشه خودمون هم اخطار نگیریم حداقل تاپیک که میپره.



سئوال بعدی اینکه چرا پروسه ی سی شارپ مون ، وقتی خودمون اصلا نخ ای درست نمیکنیم ، در برنامه ی Resource Monitor در قسمت Threads اش میگه بیش از 1 نخ داره؟ (معمولا بین 8 تا 15 نخ میگه داره) . اینها ، نخ هایی هست که خود clr ایجاد میکنه؟
خیلی ممنون استاد از جواب تون :قلب:
بله، مربوط به NET. و GC و ... میشن.

SajjadKhati
سه شنبه 05 آذر 1398, 21:49 عصر
دقیقا، میگه درگیر شد، ولی نمیگه موازی درگیر شد یا همگام. به این مساله توجه کنید که شما با دو نخ دو تا هسته رو درگیر می کنید ولی خروجی 2 برابر که نمی گیرید. این اجرا موازیه؟ اگر موازیه و مستقل ئه چرا اینقدر سربار داره؟


خیلی ممنون استاد .
بذارید فعلا ، فقط این تیکه تون را جواب بدم . ممنون از بقیه ی قسمت های جوابی که دادین . :قلب:

وقتی توی پردازنده ی 4 هسته ای میگه مثلا 75 درصد پردازنده داره پروسه ی تو را پردازش میکنه (با کدهای clr مربوطه که مهم نیست) ، خوب یعنی 3 هسته را درگیر کرد دیگه . اگه درگیر شدن بصورت همگام بوده باشه که دیگه 75 درصد نمیشه . میشه 25 درصد چون در یک لحظه ، فقط یک هسته داره کد را اجرا میکنه .
اتفاقا خروجی 2 برابر میگیریم دیگه (همون کد اول در پست اول که 2 برابر سریعتر از خروجی کد دوم در پست دوم هه)
بعد اینکه اگه در برنامه ی خودتون هم اگه فقط یک هسته را فعال کنیم و بیش از 2 نخ را اجرا کنیم ، کارایی کمتر میشه پس این نشون میده که در این صورت 2 نخ در یک هسته اجرا میشن (اگه فقط یک هسته را فعال کنیم و تیک بزنیم) (چون گفتید این افزایش کارایی بخاطر اینه که وقتی یک نخ اجرا میکنیم ، کل یک هسته تمام توانش را برای کد ما نمیذاره اما با ایجاد چند نخ و سوئیچ اون (تک) هسته روی نخ هامون ، به این دلیل هست که کارایی اش افزایش پیدا میکنه .




از طرف دیگه چرا باید کارایی 90 درصد بالاتر بره؟ با چه فرمولی همچین محاسبه ای کردید؟ در پردازش موازی دو برابر شدن تعداد هسته ها به دو برابر شدن کارایی ختم نمیشه.


در این صورت گفتم کارایی ، حداقل باید 90 درصد افزایش پیدا کنه (یعنی حداقل نزدیک به دو برابر بیشتر بشه) که اولا نقاط بحرانی در نخ هامون وجود نداشته باشه ( که همونطور که میدونید ، مثلا به متغییر مشترکی در چند نخ نخوایم مشترکا دسترسی پیدا کنیم و بخونیم یا توش بنویسیم) و همچنین یه برنامه ای رو در تک هسته و تک نخ در قیاس با یه برنامه ای رو که در چهار هسته (و چهار نخ) اجرا کنیم ، گفتم . یعنی هر هسته ، تقریبا 30 درصد افزایش کارایی داشته باشه که در یه پردازنده ی 4 هسته ای (به نسبت تک هسته ای تک نخ) میشه 3*30 که میشه 90 درصد . یعنی یه برنامه ی 4 نخ هه (که در 4 هسته اجرا میشه و نقاط بحرانی نداره) حداقل باید 90 درصد یعنی 2 برابر سریعتر از حالت تک هسته ای باشه . مثل کد اول در پست اول که دادم .

و منظورم این بود که اگه کلاس Thread ها فقط از یک هسته (بصورت همزمان) استفاده میکنن اما در عوض کلاس Parallel ها از چند هسته (بصورت همزمان) میتونن استفاده کنن ، پس توی الگوریتمی که در پست 5 دادید یا کد اول که در پست اول دادم (که نقاط بحرانی هم ندارن) رو وقتی در پردازنده ی 4 هسته (ی فیزیکی) اجرا میکنیم ، پس حداقل باید تفاوت 2 برابر اجرای سریعتر در کلاس Parallel ببینیم (چون همزمان در 4 هسته اجرا میشه) اما این اختلاف در بیشترین حد خودش به 10 درصد هم نمیرسه . گاها با هم برابر و گاها هم کلاس Thread بهتر عمل میکنه .


قضیه ی بعدی اینکه من وقتی توی پردازنده ام 4 نخ ایجاد میکنم (مثلا کد اول در پست اول را در 4 نخ اجرا میکنم) ، چون کارکرد پردازنده گاها تا 100 درصد میرسه (نمیدونم چرا گاها تا 85 و گاها تا 95 و گاها تا 99 و حتی گاها تا 100 درصد کارکرد پردازنده میره) ، یعنی در واقع اون مواقعی که کارکردش تا 100 درصد میرسه ، سیستم ام کم میاره و حتی موس رو هم بخوبی نمیتونم حرکت بدم و بصورت واضح موسم بسیار کند حرکت میکنه . خوب اگه توی یه هسته کدم بصورت همزمان اجرا میشد ، پس 3 هسته ی دیگه ام آزاد میبود و دیگه پردازش نخ مربوط به عملیات موس که نباید با مشکل کندی شدید رو به رو میشد .

the king
سه شنبه 05 آذر 1398, 23:48 عصر
خیلی ممنون استاد .
بذارید فعلا ، فقط این تیکه تون را جواب بدم . ممنون از بقیه ی قسمت های جوابی که دادین . :قلب:

وقتی توی پردازنده ی 4 هسته ای میگه مثلا 75 درصد پردازنده داره پروسه ی تو را پردازش میکنه (با کدهای clr مربوطه که مهم نیست) ، خوب یعنی 3 هسته را درگیر کرد دیگه . اگه درگیر شدن بصورت همگام بوده باشه که دیگه 75 درصد نمیشه

. میشه 25 درصد چون در یک لحظه ، فقط یک هسته داره کد را اجرا میکنه .

چرا نمیشه، سر همین چیزی که میگید تامل کنید، وقتی یک هسته در حال سوئیچ کردن به نخ شما است، یا در حال انتقال وضعیت اجرایی برنامه شما به هسته دیگری است داره کد نخ شما رو اجرا می کنه؟ نه.
چه هسته ای که داره وضعیت اجرایی بهش منتقل میشه و چه هسته ای که داره وضعیت اجرایی ازش منتقل میشه درگیر برنامه شما هستند، طبیعیه که چون وقتشون رو برنامه شما گرفته busy بودن شون رو پای برنامه شما بنویسند ولی این مواقع که کدی از نخ شما رو اجرا نمی کنند، فقط درگیر برنامه شما هستند. وقت و توان شون رو میگیره ولی یک عدد کد هم از نخ تون اجرا نمیشه. حالا این تعداد سوئیچ ها چقدر ئه؟ خیلی زیاد.
هسته پردازنده که فقط دو حالت براش پیش نمیاد که یا نخ شما رو اجرا بکنه یا اصلا کاری به برنامه شما نداشته باشه، کاری که در مورد برنامه شما داره انجام میده که فقط اجرای نخ نیست.
شما میخواهید از یک خونه به خونه دیگه اسباب کشی کنین با یک بشکن که وسایل خونه از این خونه نمیپرن وسط اتاق اون یکی خونه. پردازنده برای اینکار ها هم باید زمان صرف کنه.




اتفاقا خروجی 2 برابر میگیریم دیگه (همون کد اول در پست اول که 2 برابر سریعتر از خروجی کد دوم در پست دوم هه)
بعد اینکه اگه در برنامه ی خودتون هم اگه فقط یک هسته را فعال کنیم و بیش از 2 نخ را اجرا کنیم ، کارایی کمتر میشه پس این نشون میده که در این صورت 2 نخ در یک هسته اجرا میشن (اگه فقط یک هسته را فعال کنیم و تیک بزنیم) (چون گفتید این افزایش کارایی بخاطر اینه که وقتی یک نخ اجرا میکنیم ، کل یک هسته تمام توانش را برای کد ما نمیذاره اما با ایجاد چند نخ و سوئیچ اون (تک) هسته روی نخ هامون ، به این دلیل هست که کارایی اش افزایش پیدا میکنه .

متوجه نشدم مشکلتون با حرفی که زدم چیه.
وقتی شما بیش از یک نخ دارید سهم تون از درخواست های پردازش بیشتر میشه، سیستم عامل یک صف درخواست ها داره که باید بهشون پاسخ بده، شما که دو تا نخ در این صف میذارید طبعا سیستم عامل رو در مجموع بیشتر پاسخگو کردید، مثل همون مثال نانوایی.



در این صورت گفتم کارایی ، حداقل باید 90 درصد افزایش پیدا کنه (یعنی حداقل نزدیک به دو برابر بیشتر بشه) که اولا نقاط بحرانی در نخ هامون وجود نداشته باشه ( که همونطور که میدونید ، مثلا به متغییر مشترکی در چند نخ نخوایم مشترکا دسترسی پیدا کنیم و بخونیم یا توش بنویسیم) و همچنین یه برنامه ای رو در تک هسته و تک نخ در قیاس با یه برنامه ای رو که در چهار هسته (و چهار نخ) اجرا کنیم ، گفتم . یعنی هر هسته ، تقریبا 30 درصد افزایش کارایی داشته باشه که در یه پردازنده ی 4 هسته ای (به نسبت تک هسته ای تک نخ) میشه 3*30 که میشه 90 درصد . یعنی یه برنامه ی 4 نخ هه (که در 4 هسته اجرا میشه و نقاط بحرانی نداره) حداقل باید 90 درصد یعنی 2 برابر سریعتر از حالت تک هسته ای باشه . مثل کد اول در پست اول که دادم .

90 رو گفتید از 30 * 3 بدست آوردید، این 30 درصد رو از روی چی حساب کردید؟
به این موارد توجه نمی کنید. سیستم عامل داره پاسخگوی نیاز یک عالمه برنامه میشه که برنامه شما صرفا یکی از اونها است. برای اینکه بتونه پاسخگوی نیاز سایر پروسه ها باشه ناچاره نخ های شما رو متوقف کنه. هر چقدر تلاش کنید بیشتر ازش پاسخگویی بگیرید همونقدر سربار بیشتری تحمیل میشه، شما که نمیتوانید 4 هسته رو تخصیص بدید به پروسه برنامه خودتون و بقیه پروسه ها رو در نظر نگیرید. وقتی شما تعداد نخ ها رو افزایش میدید سیستم عامل برای اینکه بتونه هسته آزاد پیدا کنه مجبور میشه دائم نخ ها رو به حالت تعلیق ببره و هی سوئیچ بین هسته ای انجام بده.



و منظورم این بود که اگه کلاس Thread ها فقط از یک هسته (بصورت همزمان) استفاده میکنن اما در عوض کلاس Parallel ها از چند هسته (بصورت همزمان) میتونن استفاده کنن ، پس توی الگوریتمی که در پست 5 دادید یا کد اول که در پست اول دادم (که نقاط بحرانی هم ندارن) رو وقتی در پردازنده ی 4 هسته (ی فیزیکی) اجرا میکنیم ، پس حداقل باید تفاوت 2 برابر اجرای سریعتر در کلاس Parallel ببینیم (چون همزمان در 4 هسته اجرا میشه) اما این اختلاف در بیشترین حد خودش به 10 درصد هم نمیرسه . گاها با هم برابر و گاها هم کلاس Thread بهتر عمل میکنه .
اولا مایکروسافت ادعا نکرده هر چی هسته روی پردازنده هست رو برای اجرا در Parallel بکار میبره، شما جایی همچین چیزی خوندین؟ در ضمن Parallel معجزه که نمیتونه بکنه، قدری از محدودیت های NET. کم می کنه، وگرنه از اساس معماری ماشین مجازی NET. رو تغییر نمیده.
در مستنداتش هم با اجرای ساده در همون تک نخ مقایسه شده که فرضا اجراش 4 برابر سریعتر شده، با احرای چند نخی مقایسه نشده. اونم میگه متناسب با افزایش تعداد هسته (proportionately) بهبود کارایی نشون میده، نمیگه نسبت به اجرای چند نخی بهبود کارایی آنچنانی نشون میده.


For parallel loops, the degree of parallelism doesn't need to be specified by your code. Instead, the run-time environment executes the steps of the loop at the same time on as many cores as it can. The loop works correctly no matter how many cores are available. If there is only one core, the performance is close to (perhaps within a few percentage points of) the sequential equivalent. If there are multiple cores, performance improves; in many cases, performance improves proportionately with the number of cores.

از طرف دیگه ما که نمیدونیم چقدر این نخ ها بهم وابسته هستند، نمیدونیم که چقدر به هماهنگی با هم نیاز دارند، از چیزی که در ماشین مجازی میگذره که خبر نداریم. نمیدونیم کدوم کد ها و کدوم نخ های هماهنگ کننده سربار ایجاد می کنند.
فقط یکسری توصیه هایی اینور و اونور پیدا میشه که شاید کمک کنه برای نوشتن کد های مناسبتر.

mrmehdi
چهارشنبه 06 آذر 1398, 04:23 صبح
چرا نمیشه، سر همین چیزی که میگید تامل کنید، وقتی یک هسته در حال سوئیچ کردن به نخ شما است، یا در حال انتقال وضعیت اجرایی برنامه شما به هسته دیگری است داره کد نخ شما رو اجرا می کنه؟ نه.
چه هسته ای که داره وضعیت اجرایی بهش منتقل میشه و چه هسته ای که داره وضعیت اجرایی ازش منتقل میشه درگیر برنامه شما هستند، طبیعیه که چون وقتشون رو برنامه شما گرفته busy بودن شون رو پای برنامه شما بنویسند ولی این مواقع که کدی از نخ شما رو اجرا نمی کنند، فقط درگیر برنامه شما هستند. وقت و توان شون رو میگیره ولی یک عدد کد هم از نخ تون اجرا نمیشه. حالا این تعداد سوئیچ ها چقدر ئه؟ خیلی زیاد.
هسته پردازنده که فقط دو حالت براش پیش نمیاد که یا نخ شما رو اجرا بکنه یا اصلا کاری به برنامه شما نداشته باشه، کاری که در مورد برنامه شما داره انجام میده که فقط اجرای نخ نیست.
شما میخواهید از یک خونه به خونه دیگه اسباب کشی کنین با یک بشکن که وسایل خونه از این خونه نمیپرن وسط اتاق اون یکی خونه. پردازنده برای اینکار ها هم باید زمان صرف کنه.



متوجه نشدم مشکلتون با حرفی که زدم چیه.
وقتی شما بیش از یک نخ دارید سهم تون از درخواست های پردازش بیشتر میشه، سیستم عامل یک صف درخواست ها داره که باید بهشون پاسخ بده، شما که دو تا نخ در این صف میذارید طبعا سیستم عامل رو در مجموع بیشتر پاسخگو کردید، مثل همون مثال نانوایی.


90 رو گفتید از 30 * 3 بدست آوردید، این 30 درصد رو از روی چی حساب کردید؟
به این موارد توجه نمی کنید. سیستم عامل داره پاسخگوی نیاز یک عالمه برنامه میشه که برنامه شما صرفا یکی از اونها است. برای اینکه بتونه پاسخگوی نیاز سایر پروسه ها باشه ناچاره نخ های شما رو متوقف کنه. هر چقدر تلاش کنید بیشتر ازش پاسخگویی بگیرید همونقدر سربار بیشتری تحمیل میشه، شما که نمیتوانید 4 هسته رو تخصیص بدید به پروسه برنامه خودتون و بقیه پروسه ها رو در نظر نگیرید. وقتی شما تعداد نخ ها رو افزایش میدید سیستم عامل برای اینکه بتونه هسته آزاد پیدا کنه مجبور میشه دائم نخ ها رو به حالت تعلیق ببره و هی سوئیچ بین هسته ای انجام بده.


اولا مایکروسافت ادعا نکرده هر چی هسته روی پردازنده هست رو برای اجرا در Parallel بکار میبره، شما جایی همچین چیزی خوندین؟ در ضمن Parallel معجزه که نمیتونه بکنه، قدری از محدودیت های NET. کم می کنه، وگرنه از اساس معماری ماشین مجازی NET. رو تغییر نمیده.
در مستنداتش هم با اجرای ساده در همون تک نخ مقایسه شده که فرضا اجراش 4 برابر سریعتر شده، با احرای چند نخی مقایسه نشده. اونم میگه متناسب با افزایش تعداد هسته (proportionately) بهبود کارایی نشون میده، نمیگه نسبت به اجرای چند نخی بهبود کارایی آنچنانی نشون میده.

از طرف دیگه ما که نمیدونیم چقدر این نخ ها بهم وابسته هستند، نمیدونیم که چقدر به هماهنگی با هم نیاز دارند، از چیزی که در ماشین مجازی میگذره که خبر نداریم. نمیدونیم کدوم کد ها و کدوم نخ های هماهنگ کننده سربار ایجاد می کنند.
فقط یکسری توصیه هایی اینور و اونور پیدا میشه که شاید کمک کنه برای نوشتن کد های مناسبتر.

درود بر شما دوست عزیز
بسیار لذت بردم از خوندن مطالبتون و متشکرم از طرف خودم بابت به اشتراک گذاشتن این اطلاعات جذاب
خطاب به دوست عزیز که این موضوع رو شروع کردن یک نکته ای هم من عرض کنم که جناب کینگ هم بهش اشاره کردن قطعا روش صحیح پیاده سازی الگوریتم های پردازشی برای افزایش پرفورمنس برنامه های ماست. همیشه نکات ریزی وجود داره که تو بحث اشارگر ها باهاش برخورد میکنیم که به شدت توی پرفورمنس الگوریتم های پردازشی تاثیر گذار هست. سعی کنید بیشتر روی این موارد اطلاعات کسب کنید و مدیریت منابع رو به همون سیستم عامل واگذار کنید چون در نهایت شما دخل و تصرفی روی الگوریتم هایی که سیستم عامل برای مدریت منابع موردنیاز هر تسک پردازشی خودش ایجاد میکنه ندارید.

SajjadKhati
چهارشنبه 06 آذر 1398, 08:36 صبح
چرا نمیشه، سر همین چیزی که میگید تامل کنید، وقتی یک هسته در حال سوئیچ کردن به نخ شما است، یا در حال انتقال وضعیت اجرایی برنامه شما به هسته دیگری است داره کد نخ شما رو اجرا می کنه؟ نه.
چه هسته ای که داره وضعیت اجرایی بهش منتقل میشه و چه هسته ای که داره وضعیت اجرایی ازش منتقل میشه درگیر برنامه شما هستند، طبیعیه که چون وقتشون رو برنامه شما گرفته busy بودن شون رو پای برنامه شما بنویسند ولی این مواقع که کدی از نخ شما رو اجرا نمی کنند، فقط درگیر برنامه شما هستند. وقت و توان شون رو میگیره ولی یک عدد کد هم از نخ تون اجرا نمیشه. حالا این تعداد سوئیچ ها چقدر ئه؟ خیلی زیاد.
هسته پردازنده که فقط دو حالت براش پیش نمیاد که یا نخ شما رو اجرا بکنه یا اصلا کاری به برنامه شما نداشته باشه، کاری که در مورد برنامه شما داره انجام میده که فقط اجرای نخ نیست.
شما میخواهید از یک خونه به خونه دیگه اسباب کشی کنین با یک بشکن که وسایل خونه از این خونه نمیپرن وسط اتاق اون یکی خونه. پردازنده برای اینکار ها هم باید زمان صرف کنه.


خیلی ممنون استاد .
پس این طور که شما میگید ، در آنِ واحد (و در یک لحظه) ، تهش فقط دو هسته (ی منطقی یا فیزیکی) باید درگیر باشن . در همون لحظه ، حداقل کارکرد بقیه ی هسته ها ، حداقل اینکه باید پایین بیاد .
بالاخره با این توضیحات تون ، نمیتونم قبول کنم که در یک لحظه ، بیش از دو هسته درگیر پروسه ام باشه . درصورتی که کد اول در پست اول را اگه در 4 نخ درون پردازنده ی من اجرا کنم ، پروسه ام ، حداقل بیش از 85 درصد پردازنده را اشغال میکنه (یعنی حداقل 3 هسته بصورت همزمان) و گاها تا 100 درصد هم میره که باعث میشه به مدت مدیدی حتی پردازنده ، به نخ مربوط به موس ام هم پاسخگو نباشه و رسم موس خیلی کند صورت بگیره .

یا همون کد (اول در پست اول) را در پردازنده تون وقتی که 8 نخ کردید اجرا کنید ، باز هم باید آمار اشغال پردازنده تون بیش از 85 درصد (و شاید هم مثل من گاها تا 100 درصد) بره . وگرنه طبق گفته ی شما ، پروسه ی برنامه ، همزمان باید 2 هسته ی منطقی از پردازنده تون یعنی 25 درصد از پردازنده تون (یا تهش دیگه 2 هسته ی فیزیکی که میشه 4 هسته ی منطقی از پردازنده تون یعنی 50 درصد از پردازنده تون) را اشغال کنه .

بعد اینکه اگه وقتی از کلاس Thread کدمون را اجرا میکنیم ، کدمون فقط درون یک هسته (بصورت همزمان) اجرا میشه ، پس نباید وقتی که درون Task Manager روی پروسه مون کلیک راست و Set Affinity را روی یک هسته فقط ست میکنیم ، کارایی هر تعداد نخ ای که میسازیم ، متفاوت باشه . درسته؟
اما وقتی این کار را کنید و کد اول در پست اول را که دادم اجرا کنید ، میبینید زمان اجراش 2 برابر بیشتر طول میکشه .
این دلیل هم کافی نیست که وقتی از کلاس Thread استفاده میکنیم ، به همون تعدادِ نخ مون ، توی چند هسته ی منطقی (و فیزیکی) بصورت همزمان اجرا میشن؟

در آخر پست 20 هم یه قضیه ی دیگه را هم اضافه کرده بودم :

"
قضیه ی بعدی اینکه من وقتی توی پردازنده ام 4 نخ ایجاد میکنم (مثلا کد اول در پست اول را در 4 نخ اجرا میکنم) ، چون کارکرد پردازنده گاها تا 100 درصد میرسه (نمیدونم چرا گاها تا 85 و گاها تا 95 و گاها تا 99 و حتی گاها تا 100 درصد کارکرد پردازنده میره) ، یعنی در واقع اون مواقعی که کارکردش تا 100 درصد میرسه ، سیستم ام کم میاره و حتی موس رو هم بخوبی نمیتونم حرکت بدم و بصورت واضح موسم بسیار کند حرکت میکنه . خوب اگه توی یه هسته کدم بصورت همزمان اجرا میشد ، پس 3 هسته ی دیگه ام آزاد میبود و دیگه پردازش نخ مربوط به عملیات موس که نباید با مشکل کندی شدید رو به رو میشد .
"




متوجه نشدم مشکلتون با حرفی که زدم چیه.
وقتی شما بیش از یک نخ دارید سهم تون از درخواست های پردازش بیشتر میشه، سیستم عامل یک صف درخواست ها داره که باید بهشون پاسخ بده، شما که دو تا نخ در این صف میذارید طبعا سیستم عامل رو در مجموع بیشتر پاسخگو کردید، مثل همون مثال نانوایی.


90 رو گفتید از 30 * 3 بدست آوردید، این 30 درصد رو از روی چی حساب کردید؟
به این موارد توجه نمی کنید. سیستم عامل داره پاسخگوی نیاز یک عالمه برنامه میشه که برنامه شما صرفا یکی از اونها است. برای اینکه بتونه پاسخگوی نیاز سایر پروسه ها باشه ناچاره نخ های شما رو متوقف کنه. هر چقدر تلاش کنید بیشتر ازش پاسخگویی بگیرید همونقدر سربار بیشتری تحمیل میشه، شما که نمیتوانید 4 هسته رو تخصیص بدید به پروسه برنامه خودتون و بقیه پروسه ها رو در نظر نگیرید. وقتی شما تعداد نخ ها رو افزایش میدید سیستم عامل برای اینکه بتونه هسته آزاد پیدا کنه مجبور میشه دائم نخ ها رو به حالت تعلیق ببره و هی سوئیچ بین هسته ای انجام بده.


اولا مایکروسافت ادعا نکرده هر چی هسته روی پردازنده هست رو برای اجرا در Parallel بکار میبره، شما جایی همچین چیزی خوندین؟ در ضمن Parallel معجزه که نمیتونه بکنه، قدری از محدودیت های NET. کم می کنه، وگرنه از اساس معماری ماشین مجازی NET. رو تغییر نمیده.
در مستنداتش هم با اجرای ساده در همون تک نخ مقایسه شده که فرضا اجراش 4 برابر سریعتر شده، با احرای چند نخی مقایسه نشده. اونم میگه متناسب با افزایش تعداد هسته (proportionately) بهبود کارایی نشون میده، نمیگه نسبت به اجرای چند نخی بهبود کارایی آنچنانی نشون میده.

از طرف دیگه ما که نمیدونیم چقدر این نخ ها بهم وابسته هستند، نمیدونیم که چقدر به هماهنگی با هم نیاز دارند، از چیزی که در ماشین مجازی میگذره که خبر نداریم. نمیدونیم کدوم کد ها و کدوم نخ های هماهنگ کننده سربار ایجاد می کنند.
فقط یکسری توصیه هایی اینور و اونور پیدا میشه که شاید کمک کنه برای نوشتن کد های مناسبتر.


وقتی یه هسته ی فیزیکی را 100 درصد بگیم که کارایی داره ، حالا وقتی که یه کدی که همزمان از 2 هسته ی فیزیکی استفاده میکنه و در صورتی که بهینه باشه و مناطق بحرانی نداشته باشه (یعنی همزمان چند هسته نخوان از حافظه ی مشترکی بخونن یا بنویسن) ، در این شرایط ، از اون 100 درصدِ کارایی هر هسته (ی فیزیکی) ، حداقل 30 درصد بازدهی داره که (یه چیزهای سطحی خوندم و فکر کنم قانونی بنام amdh نمیدونم چی چی :لبخند: اینو میگه) . اگه کد ، نقاط بحرانی نداشته باشه و یا خیلی کم داشته باشه ، و هر هسته بخواد 30 درصد از کاراییِ 100 درصدش را هم نداشته باشه که اصلا پردازنده ی چند هسته ای واسه چی بسازن؟
در این صورت حتی با 4 برابر شدن هسته ، پردازش و کارایی ، به کمتر از 2 برابر میرسه . (قبول دارم کد بهینه نباشه ، کارایی بصورت همزمان و در چند هسته ، حتی کم هم ممکنه بشه . منظورم روی کد کاملا بهینه هست) .

بله میدونم در کلاس Parallel ، ممکنه در چند هسته بصورت همزمان اجرا بشه . ممکنه هم نشه .
خیلی ممنون استاد .
از دوست مون هم بابت مطلبش متشکرم .

the king
چهارشنبه 06 آذر 1398, 11:04 صبح
خیلی ممنون استاد .
پس این طور که شما میگید ، در آنِ واحد (و در یک لحظه) ، تهش فقط دو هسته (ی منطقی یا فیزیکی) باید درگیر باشن . در همون لحظه ، حداقل کارکرد بقیه ی هسته ها ، حداقل اینکه باید پایین بیاد .

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


بالاخره با این توضیحات تون ، نمیتونم قبول کنم که در یک لحظه ، بیش از دو هسته درگیر پروسه ام باشه . درصورتی که کد اول در پست اول را اگه در 4 نخ درون پردازنده ی من اجرا کنم ، پروسه ام ، حداقل بیش از 85 درصد پردازنده را اشغال میکنه (یعنی حداقل 3 هسته بصورت همزمان) و گاها تا 100 درصد هم میره که باعث میشه به مدت مدیدی حتی پردازنده ، به نخ مربوط به موس ام هم پاسخگو نباشه و رسم موس خیلی کند صورت بگیره .




یا همون کد (اول در پست اول) را در پردازنده تون وقتی که 8 نخ کردید اجرا کنید ، باز هم باید آمار اشغال پردازنده تون بیش از 85 درصد (و شاید هم مثل من گاها تا 100 درصد) بره . وگرنه طبق گفته ی شما ، پروسه ی برنامه ، همزمان باید 2 هسته ی منطقی از پردازنده تون یعنی 25 درصد از پردازنده تون (یا تهش دیگه 2 هسته ی فیزیکی که میشه 4 هسته ی منطقی از پردازنده تون یعنی 50 درصد از پردازنده تون) را اشغال کنه .

این موارد رو بررسی کنید.
اگر دو نسخه فایل اجرایی اون برنامه ProcessThreads رو اجرا کنید و در هر کدوم یک نخ بسازید و بدون محدودیت در CPU ها همزمان اجرا بشن، Total usage و CPU usage شون نسبت به وقتی که تنهایی اجراشون می کردید کاهش پیدا می کنه یا نه؟
هر دو حالت رو امتحان کنید. حتی بعدش CPU ها رو نصف کنید و نیمی رو در این یکی برنامه تیک بزنید و نیمی در اون یکی برنامه و مجددا یک نخ در هر کدوم اضافه کنید تا همزمان اجرا بشن.
آمار همچنان نسبت به اجرای تنهایی یک نخ در یک برنامه کمتره.
دو تا برنامه جدا هستند، پروسه هاشون مجزا است و میگید نمی تونم بپذیرم که بیش از دو هسته برای هر کدوم درگیر باشن. پس چه توضیحی دارید برای اینکه کارکرد شون کاهش پیدا کرد؟




بعد اینکه اگه وقتی از کلاس Thread کدمون را اجرا میکنیم ، کدمون فقط درون یک هسته (بصورت همزمان) اجرا میشه ، پس نباید وقتی که درون Task Manager روی پروسه مون کلیک راست و Set Affinity را روی یک هسته فقط ست میکنیم ، کارایی هر تعداد نخ ای که میسازیم ، متفاوت باشه . درسته؟

نه. درست نیست. مثل اینه که برید توی بانک و نوبت بگیرید و بعد بگن آقا شماره تون رو صدا کردن برید باجه شماره 3، بعد بگید نخیر من فقط باجه شماره 5 میرم، صبر میکنم تا سرش خلوت بشه.
وقتی تعداد انتخاب ها بیشتر باشه دست سیستم عامل باز تر خواهد بود. فقط زمانی این انتخاب انحصاری میتونست مفید باشه که به هر دلیلی سیستم عامل اون هسته رو همیشه بیکار نگه داشته بود که بصورت عادی همچین کاری رو با منابع با ارزشش نمی کنه.



اما وقتی این کار را کنید و کد اول در پست اول را که دادم اجرا کنید ، میبینید زمان اجراش 2 برابر بیشتر طول میکشه .
این دلیل هم کافی نیست که وقتی از کلاس Thread استفاده میکنیم ، به همون تعدادِ نخ مون ، توی چند هسته ی منطقی (و فیزیکی) بصورت همزمان اجرا میشن؟

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



قضیه ی بعدی اینکه من وقتی توی پردازنده ام 4 نخ ایجاد میکنم (مثلا کد اول در پست اول را در 4 نخ اجرا میکنم) ، چون کارکرد پردازنده گاها تا 100 درصد میرسه (نمیدونم چرا گاها تا 85 و گاها تا 95 و گاها تا 99 و حتی گاها تا 100 درصد کارکرد پردازنده میره) ، یعنی در واقع اون مواقعی که کارکردش تا 100 درصد میرسه ، سیستم ام کم میاره و حتی موس رو هم بخوبی نمیتونم حرکت بدم و بصورت واضح موسم بسیار کند حرکت میکنه . خوب اگه توی یه هسته کدم بصورت همزمان اجرا میشد ، پس 3 هسته ی دیگه ام آزاد میبود و دیگه پردازش نخ مربوط به عملیات موس که نباید با مشکل کندی شدید رو به رو میشد .

این همچنان ادامه همون فرض اولیه است که دارید که پردازنده یا داره کد نخ من رو اجرا میکنه یا اگه نمی کنه پس بیکار ئه.



وقتی یه هسته ی فیزیکی را 100 درصد بگیم که کارایی داره ، حالا وقتی که یه کدی که همزمان از 2 هسته ی فیزیکی استفاده میکنه و در صورتی که بهینه باشه و مناطق بحرانی نداشته باشه (یعنی همزمان چند هسته نخوان از حافظه ی مشترکی بخونن یا بنویسن) ، در این شرایط ، از اون 100 درصدِ کارایی هر هسته (ی فیزیکی) ، حداقل 30 درصد بازدهی داره که (یه چیزهای سطحی خوندم و فکر کنم قانونی بنام amdh نمیدونم چی چی :لبخند: اینو میگه) . اگه کد ، نقاط بحرانی نداشته باشه و یا خیلی کم داشته باشه ، و هر هسته بخواد 30 درصد از کاراییِ 100 درصدش را هم نداشته باشه که اصلا پردازنده ی چند هسته ای واسه چی بسازن؟
در این صورت حتی با 4 برابر شدن هسته ، پردازش و کارایی ، به کمتر از 2 برابر میرسه . (قبول دارم کد بهینه نباشه ، کارایی بصورت همزمان و در چند هسته ، حتی کم هم ممکنه بشه . منظورم روی کد کاملا بهینه هست) .

بله میدونم در کلاس Parallel ، ممکنه در چند هسته بصورت همزمان اجرا بشه . ممکنه هم نشه .
خیلی ممنون استاد .
از دوست مون هم بابت مطلبش متشکرم .
به اون آزمایش 10 ثانیه اول برنامه توجه کردید؟ اونکه دیگه بر اساس بازدهی 100 درصد هسته که نیست، معیار شهودی و تجربی ارائه میده از اینکه یک نخ در شرایطی که محدودیتی در انتخاب هسته نباشه چه قدر میتونه پاسخگویی بگیره و اون رو معیار 100 درصد میگیره.
اون موارد سربار سخت افزاری و نرم افزاری که در اجرا پیش میومده در این معیار خود به خود کسر شدن تا به 100 درصد بازدهی واقعی رسیدیم. شما که نمی توانید همچین معیار شهودی رو با هر قانون تئوریکی ترکیب کنید.

SajjadKhati
چهارشنبه 06 آذر 1398, 13:04 عصر
وقتی دو هسته درگیر اجرای برنامه شدن، طبعا باری که روی دوش سایر هسته ها می افته افزایش پیدا میکنه،


سلامی مجدد
خیلی ممنون استاد :قلب:
خوب ، منم همین رو میگم دیگه . بنابراین سایر پروسه ها و نخ ها (بجز پروسه ی من) رو سیستم عامل میندازه روی دوش 3 هسته ی دیگه که بار کاری شون خیلی کمتر هه .
دقت کنید که من فقط همین برنامه ام را که بار کاری زیادی روی پردازنده محول میکنه را اجرا میکنم . درسته سیستم عامل و پروسه ها و نخ های مربوط به برنامه های دیگه هم وجود دارن و میخوان پردازش بشن اما :
اولا بار کاری معمولی دارن (3 هسته ی دیگه ی من ، وقتی که برنامه ام را اجرا میکنم ، بار کاریِ هر هسته شون به 20 درصد از هر هسته هم نمیرسه) و
دوما 3 هسته ی بیکارِ دیگه برای پردازشِ پروسه های دیگه و نخ های مربوط بهشون وجود داره و همونطور که قبلا گفته بودید که سیستم عامل و پردازنده سعی میکنن تا جایی که ممکنه ، روی همون هسته (ی فیزیکی) ، کد پروسه ی خاص را اجرا کنن و به هسته (ی فیزیکی) دیگه ، منتقل نکنن مگر اینکه بدونن به سربارش میارزه یا گرمای اون هسته زیاد شده باشه بنابراین چیزی که در زیر گفتید ، نیاز به توضیح داره که بگم :




نه. درست نیست. مثل اینه که برید توی بانک و نوبت بگیرید و بعد بگن آقا شماره تون رو صدا کردن برید باجه شماره 3، بعد بگید نخیر من فقط باجه شماره 5 میرم، صبر میکنم تا سرش خلوت بشه.
وقتی تعداد انتخاب ها بیشتر باشه دست سیستم عامل باز تر خواهد بود. فقط زمانی این انتخاب انحصاری میتونست مفید باشه که به هر دلیلی سیستم عامل اون هسته رو همیشه بیکار نگه داشته بود که بصورت عادی همچین کاری رو با منابع با ارزشش نمی کنه.


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



اول این نکته را بگم که منظورم از صحبتی که در بالا کردم این نیست که وقتی Set Affinity را روی یه هسته برای پروسه ام متمرکز کردم ، پس سیستم عامل همه ی کدهای پروسه ی من را روش اجرا میکنه و بقیه ی نخ ها از پروسه های دیگه را اصلا روی اون هسته اجرا نمیکنه . منظورم این نیست . بلکه این هست که اولا همونطور که گفتید ، چون 3 هسته ی دیگه خالی هست و این هسته هم داره پروسه ی من را پردازش میکنه ، برای جلوگیری از سربار بیشتر ، سعی میکنه سوئیچ روی نخ های دیگه در این هسته را کمتر کنه .

علاوه بر این نکات ، نکته ی مهم اینه که حتی هم اگه سوئیچ روی نخ های پروسه های دیگه رو در این هسته ی فیزیکی ای که داره پروسه ی من را پردازش میکنه ، اصلا کم نکنه . خوب بصورت عادی ، گفتم که بار کار خاصی روی هسته ها نیست . در حد 20 درصد هم نمیشه . پس بنابراین وقتی اون برنامه ام را که اجرا میکنم (و Set Affinity را روی یه هسته برای پروسه ام متمرکز میکنم) ، اولا که اون هسته تا 100 درصد زمانش در حال کارکرد هست (منظورم این نیست که 100 درصد پردازنده داره کار انجام میده . سربار انتظار و سوئیچ اش را میدونم . بالاخره این سربارها هم از دید سیستم عامل و task manager ، اشغال هسته محسوب میشه . چه حالا میخواد پردازنده کاری انجام بده یا نه . مهم اینه که سیستم عامل نمیتونه در اون لحظه ، نخی را بهش بسپاره تا پردازش کنه) و دوما اگه سوئیچ به پروسه های دیگه رو هم در نظر بگیریم ، فقط 20 درصد از زمانش را برای پروسه های دیگه و نخ های مربوط به اون داره صرف میکنه .
پس بنابراین اگه موضوع کاهش کارایی کد باشه ، اون هسته (که برنامه ام رو روی اون هسته Set Affinity کردم) ، باید تهش 20 درصد ، کدهای (کد اول در پست اول) پروسه ام را دیرتر اجرا کنه نه 2 برابر دیرتر.
نمیدونم متوجه ی منظورم شدید یا نه .

برای من که ظاهر قضیه نشون میده که کدهای کلاس Thread هم در چند هسته ی فیزیکی بصورت همزمان انجام میشه (البته ویندوز من ویندوز 10 64 بیت 1903 هست) .
چه قضیه ی Set Affinity و چه قضیه ی قیاس کدهای کلاس Thread و کلاس Parallel (و نتیجه ی کاهش و افزایش کارایی شون را که گفتم) و بقیه ی مدارکی که اینجا گذاشتم .

SajjadKhati
چهارشنبه 06 آذر 1398, 15:14 عصر
این موارد رو بررسی کنید.
اگر دو نسخه فایل اجرایی اون برنامه ProcessThreads رو اجرا کنید و در هر کدوم یک نخ بسازید و بدون محدودیت در CPU ها همزمان اجرا بشن، Total usage و CPU usage شون نسبت به وقتی که تنهایی اجراشون می کردید کاهش پیدا می کنه یا نه؟
هر دو حالت رو امتحان کنید. حتی بعدش CPU ها رو نصف کنید و نیمی رو در این یکی برنامه تیک بزنید و نیمی در اون یکی برنامه و مجددا یک نخ در هر کدوم اضافه کنید تا همزمان اجرا بشن.
آمار همچنان نسبت به اجرای تنهایی یک نخ در یک برنامه کمتره.
دو تا برنامه جدا هستند، پروسه هاشون مجزا است و میگید نمی تونم بپذیرم که بیش از دو هسته برای هر کدوم درگیر باشن. پس چه توضیحی دارید برای اینکه کارکرد شون کاهش پیدا کرد؟


من دقیق متوجه نشدم هدف تون از این کار چیه .
به هر حال تست کردم :

1) دو برنامه ی ProcessThreads را همزمان اجرا کردم و در هر دو برنامه ، همه ی cpu ها تیک دارن .در هر کدوم از برنامه ها ، فقط یک نخ اجرا کردم (یکبار دکمه ی New Thread را کلیک کردم) .
در یکی شون ، cpu usage و total usage مقدار 94 درصد و در برنامه ی دیگری ، این موارد مقدار 92 درصد شدن . مقدار اشغال پردازنده هم 25 درصد برای هر برنامه بود .

2) دو برنامه ی ProcessThreads را همزمان اجرا کردم و در یکی شون فقط cpu 0 و cpu 1 را تیک زدم و در برنامه ی دیگری ، فقط cpu 2 و cpu 3 را تیک زدم . در هر کدوم از برنامه ها ، فقط یک نخ اجرا کردم (یکبار دکمه ی New Thread را کلیک کردم) .
در یکی شون cpu usage و total usage مقدار 85 درصد و در برنامه ی دیگری ، این موارد مقدار 93 درصد شدن . مقدار اشغال پردازنده هم 25 درصد برای هر برنامه بود .


به هر حال ، دو برنامه (و بنابراین دو پروسه ی متفاوت) ، در دو هسته ی متفاوت اجرا میشن که هر کدوم 25 درصد از پردازنده ی من را (که 4 هسته ای هست) ، اشغال میکنن (که کلا میشه 50 درصد) .
وقتی هم که در یک پروسه ، دو نخ اجرا میکنیم ، باز هم 50 درصد را اشغال میکنن .




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


متوجه نشدم منظورتون دقیقا چیه :لبخند:

the king
چهارشنبه 06 آذر 1398, 16:44 عصر
من دقیق متوجه نشدم هدف تون از این کار چیه .
به هر حال تست کردم :

1) دو برنامه ی ProcessThreads را همزمان اجرا کردم و در هر دو برنامه ، همه ی cpu ها تیک دارن .در هر کدوم از برنامه ها ، فقط یک نخ اجرا کردم (یکبار دکمه ی New Thread را کلیک کردم) .
در یکی شون ، cpu usage و total usage مقدار 94 درصد و در برنامه ی دیگری ، این موارد مقدار 92 درصد شدن . مقدار اشغال پردازنده هم 25 درصد برای هر برنامه بود .

شما وقتی در یک برنامه یک نخ رو آزادانه برای اجرا روی هر هسته ای انتخاب می کردید بهتون cpu usage و total usage بین 98 الی 100 درصد میده. درسته؟ حالا در دو برنامه رسیده به 94 و 92 درصد.
طبق ادعای شما برای اجرای این دو برنامه فقط دو هسته درگیر شدن، هر هسته برای یک نخ در یک برنامه و اون دو هسته دیگه پردازنده تون الان بیکار ئه و 25 + 25 درصد توان پردازنده مشغول ئه و 25 + 25 درصد بیکار ئه.
پس چطور این مساله رو توضیح میدید که یک هسته که 25 درصد توان پردازنده بود تونسته بود 98 الی 100 درصد کارایی بده ولی حالا که دو تا هسته شد با 50 درصد توان پردازنده کارایی شون شده 94 + 92 درصد؟
مگه شما مدعی نیستید که اون دو تا هسته دیگه الان بیکار هستند و کاری به اون دو تا نخ ندارند برای سایر کارهای سیستم عامل آزادند هر کاری لازمه بکنند؟ چطور توان دو هسته ای موازی تون اومد پایین؟
این چطور پردازش موازی ای در دو هسته فیزیکی مستقل ئه که دو تا پروسه جدا دارن ولی اجرای همزمان شون نتونسته کارایی اجرای تکی رو ارائه کنه؟



2) دو برنامه ی ProcessThreads را همزمان اجرا کردم و در یکی شون فقط cpu 0 و cpu 1 را تیک زدم و در برنامه ی دیگری ، فقط cpu 2 و cpu 3 را تیک زدم . در هر کدوم از برنامه ها ، فقط یک نخ اجرا کردم (یکبار دکمه ی New Thread را کلیک کردم) .
در یکی شون cpu usage و total usage مقدار 85 درصد و در برنامه ی دیگری ، این موارد مقدار 93 درصد شدن . مقدار اشغال پردازنده هم 25 درصد برای هر برنامه بود .

این هم مثل همون یکی. با فرض شما که مدعی هستید وقتی نخ بین CPU0 و CPU1 سوئیچ میشه سایر هسته ها آزاد هستند و درگیر نیستن، چه توضیحی دارید برای اینکه نخی که آزاد بوده در یکی از دو هسته CPU0 و CPU1 اجرا بشه روی کارکرد در هسته CPU2 و CPU3 تاثیر داره؟



به هر حال ، دو برنامه (و بنابراین دو پروسه ی متفاوت) ، در دو هسته ی متفاوت اجرا میشن که هر کدوم 25 درصد از پردازنده ی من را (که 4 هسته ای هست) ، اشغال میکنن (که کلا میشه 50 درصد) .
وقتی هم که در یک پروسه ، دو نخ اجرا میکنیم ، باز هم 50 درصد را اشغال میکنن .

و حتما می توانید توضیح بدین که چطور کارکرد این 50 درصد تون پایینتر از اجرای یک نخ شده؟ اینکه چطور با این اجرای موازی از 98 الی 100 درصد رسیدین به 94 و 92 درصد. شما که میگید من نمیتونم بپذیرم که وقتی بین دو هسته سوئیچ میشه بار کاری روی سایر هسته ها ایجاد بشه چطوری این تجربه رو تفسیر می کنید که فقط 50 درصد توان پردازنده رو گرفتید و کاری به سایر هسته ها نداشتید ولی کارکرد اومد پایینتر؟ شما که میگید پردازنده هنوز 50 درصد بیکار ئه چطور کارکرد هسته اش کم شد؟



متوجه نشدم منظورتون دقیقا چیه :لبخند:
آره، متوجه نشدین. منظور من دقیقا همون مرغی است که یه پا داره.

SajjadKhati
چهارشنبه 06 آذر 1398, 18:55 عصر
شما وقتی در یک برنامه یک نخ رو آزادانه برای اجرا روی هر هسته ای انتخاب می کردید بهتون cpu usage و total usage بین 98 الی 100 درصد میده. درسته؟ حالا در دو برنامه رسیده به 94 و 92 درصد.
طبق ادعای شما برای اجرای این دو برنامه فقط دو هسته درگیر شدن، هر هسته برای یک نخ در یک برنامه و اون دو هسته دیگه پردازنده تون الان بیکار ئه و 25 + 25 درصد توان پردازنده مشغول ئه و 25 + 25 درصد بیکار ئه.
پس چطور این مساله رو توضیح میدید که یک هسته که 25 درصد توان پردازنده بود تونسته بود 98 الی 100 درصد کارایی بده ولی حالا که دو تا هسته شد با 50 درصد توان پردازنده کارایی شون شده 94 + 92 درصد؟
مگه شما مدعی نیستید که اون دو تا هسته دیگه الان بیکار هستند و کاری به اون دو تا نخ ندارند برای سایر کارهای سیستم عامل آزادند هر کاری لازمه بکنند؟ چطور توان دو هسته ای موازی تون اومد پایین؟
این چطور پردازش موازی ای در دو هسته فیزیکی مستقل ئه که دو تا پروسه جدا دارن ولی اجرای همزمان شون نتونسته کارایی اجرای تکی رو ارائه کنه؟


خیلی ممنون استاد :قلب:
اگه منظورتون از اینکه من گفتم بیکار هستن ، یعنی سوئیچ پروسه هام روی اون هسته ها انجام نمیشه و اون هسته ها ، به این جهت بیکار هستن که چنین چیزی نگفتم و توضیح دادم دیگه .

بله . کارایی یک نخ با یک پروسه (در واقع cpu usage اش) ، برای من 98 درصد بود . و وقتی دو تا پروسه که هر کدوم شون یک نخ را توشون اجرا کردم ، این مقدار ، در یک پروسه 94 و در اون یکی پروسه ، 92 شده بود .

علت اش هم تا جایی که میدونم بخاطر قضیه ی turbo clock در پردازنده ی من هست (اگه اشتباه نکنم ها) . بعضی از پردازنده ها توربو کلاک دارن . در واقع علاوه بر کلاک پایه (که واسه ی من 3.2ghz هست) ، یه کلاک توربو (که واسه ی من 3.4ghz هست) هم دارن . فرکانس پایه ، که همیشه ثابت هست و هیچ هسته ی ای از اون پردازنده ، حق نداره از کلاک پایه ی اون پردازنده ، کلاکش کمتر بشه . یعنی اگه پردازنده ای با تمام توان اش (توان و اشغالِ 100 درصد از تمام هسته ها) کار کنه و حتی زمانی که اور کلاک میشه ، هیچ هسته ای حق نداره فرکانسش کمتر از فرکانس پایه اش بشه . اما وقتی پردازنده با توان کمتری کار کنه (مثلا وقتی با 15 درصد از توان اش کار کنه) ، پردازنده ، اتوماتیک کلاک هسته رو افزایش میده تا به کلاک توربو بوست ای که مشخص کرده بود برای اون پردازنده ، نزدیک تر بشه و هر چقدر میزان کارکرد پردازنده بیشتر بشه ، کلاک توربو بوست اش کم و کمتر میشه تا به فرکانس پایه اش نزدیک بشه .
مثلا برای من ، وقتی پردازنده ام 15 درصد مشغول هست ، با کلاک 3.35 تا 3.37 کار میکنه . وقتی 25 درصد ازش مشغول هست ، با کلاک 3.3 تا 3.5 کار میکنه . وقتی 50 درصدش مشغول هست ، با کلاک 3.25 کار میکنه و از 50 درصد به بالاتر (تا 100 درصد) با کلاک 3.19 کار میکنه .
تا اینجا را که مطمئنم اما حالا اینکه مثلا وقتی 25 درصد اش مشغول هست ، میانگین کلاک هسته ها بشه 3.5 (یعنی کلاک هر هسته با هم متفاوت باشه و در نتیجه میانگین شون بشه 3.5) یا اینکه همه ی هسته ها با کلاک 3.5 کار کنن را نمیدونم ولی اگه اشتباه نکنم ، میانگین کلاک هسته ها میشه 3.5 و بنابراین باز هم اگه اشتباه نکنم ، هسته ها با کلاک های متفاوتی کار میکنند و در نتیجه ، وقتی یک پروسه رو اجرا میکنیم ، مقدار cpu usage اش 98 درصد میشه اما وقتی دو تا پروسه را اجرا میکنیم این مقدار در یک پروسه ، 94 و در پروسه ی دیگه 92 میشه .
البته اینی که کلاک هسته ها در پردازنده های دارای تکنولوژی turbo boost clock ، متفاوت خواهد بود یا نه را باید تحقیق بشه (من فعلا اینترنت بین الملل ندارم) ولی به احتمال بسیار زیاد (95 درصد) ، همینطور هست.





این هم مثل همون یکی. با فرض شما که مدعی هستید وقتی نخ بین CPU0 و CPU1 سوئیچ میشه سایر هسته ها آزاد هستند و درگیر نیستن، چه توضیحی دارید برای اینکه نخی که آزاد بوده در یکی از دو هسته CPU0 و CPU1 اجرا بشه روی کارکرد در هسته CPU2 و CPU3 تاثیر داره؟


من اینم بگم قشنگ متوجه ی منظورتون نشدم ، قضیه ی مرغ را پیش نمیکشید :لبخند:



و حتما می توانید توضیح بدین که چطور کارکرد این 50 درصد تون پایینتر از اجرای یک نخ شده؟ اینکه چطور با این اجرای موازی از 98 الی 100 درصد رسیدین به 94 و 92 درصد. شما که میگید من نمیتونم بپذیرم که وقتی بین دو هسته سوئیچ میشه بار کاری روی سایر هسته ها ایجاد بشه چطوری این تجربه رو تفسیر می کنید که فقط 50 درصد توان پردازنده رو گرفتید و کاری به سایر هسته ها نداشتید ولی کارکرد اومد پایینتر؟ شما که میگید پردازنده هنوز 50 درصد بیکار ئه چطور کارکرد هسته اش کم شد؟


آره، متوجه نشدین. منظور من دقیقا همون مرغی است که یه پا داره.


این هم مثل قضیه ی بالا (توربو کلاک) که گفتم .
البته شاید وقتی بین دو هسته میخواد سوئیچ بشه ، وقتی از حافظه ی مشترک بین تمام هسته های فیزیکی (که اگه اشتباه نکنم ، حافظه ی کش سطح l3 ، حافظه ی مشترک بین تمام هسته های فیزیکی هست . درسته؟) شاید نیاز داشته باشه که این دو هسته برای انتقال کارهاشون ازش استفاده کنن که در این صورت چون حافظه ی مشترک هست ، در یک لحظه ، فقط یک هسته قطعا میتونه ازش استفاده کنه و سایر هسته ها نمیتونن و سربار ایجاد کنه ولی غیر از این حالت ها منظورم بود .

the king
چهارشنبه 06 آذر 1398, 20:12 عصر
خیلی ممنون استاد :قلب:
اگه منظورتون از اینکه من گفتم بیکار هستن ، یعنی سوئیچ پروسه هام روی اون هسته ها انجام نمیشه و اون هسته ها ، به این جهت بیکار هستن که چنین چیزی نگفتم و توضیح دادم دیگه .

بله . کارایی یک نخ با یک پروسه (در واقع cpu usage اش) ، برای من 98 درصد بود . و وقتی دو تا پروسه که هر کدوم شون یک نخ را توشون اجرا کردم ، این مقدار ، در یک پروسه 94 و در اون یکی پروسه ، 92 شده بود .

علت اش هم تا جایی که میدونم بخاطر قضیه ی turbo clock در پردازنده ی من هست (اگه اشتباه نکنم ها) . بعضی از پردازنده ها توربو کلاک دارن . در واقع علاوه بر کلاک پایه (که واسه ی من 3.2ghz هست) ، یه کلاک توربو (که واسه ی من 3.4ghz هست) هم دارن . فرکانس پایه ، که همیشه ثابت هست و هیچ هسته ی ای از اون پردازنده ، حق نداره از کلاک پایه ی اون پردازنده ، کلاکش کمتر بشه . یعنی اگه پردازنده ای با تمام توان اش (توان و اشغالِ 100 درصد از تمام هسته ها) کار کنه و حتی زمانی که اور کلاک میشه ، هیچ هسته ای حق نداره فرکانسش کمتر از فرکانس پایه اش بشه . اما وقتی پردازنده با توان کمتری کار کنه (مثلا وقتی با 15 درصد از توان اش کار کنه) ، پردازنده ، اتوماتیک کلاک هسته رو افزایش میده تا به کلاک توربو بوست ای که مشخص کرده بود برای اون پردازنده ، نزدیک تر بشه و هر چقدر میزان کارکرد پردازنده بیشتر بشه ، کلاک توربو بوست اش کم و کمتر میشه تا به فرکانس پایه اش نزدیک بشه .
مثلا برای من ، وقتی پردازنده ام 15 درصد مشغول هست ، با کلاک 3.35 تا 3.37 کار میکنه . وقتی 25 درصد ازش مشغول هست ، با کلاک 3.3 تا 3.5 کار میکنه . وقتی 50 درصدش مشغول هست ، با کلاک 3.25 کار میکنه و از 50 درصد به بالاتر (تا 100 درصد) با کلاک 3.19 کار میکنه .
تا اینجا را که مطمئنم اما حالا اینکه مثلا وقتی 25 درصد اش مشغول هست ، میانگین کلاک هسته ها بشه 3.5 (یعنی کلاک هر هسته با هم متفاوت باشه و در نتیجه میانگین شون بشه 3.5) یا اینکه همه ی هسته ها با کلاک 3.5 کار کنن را نمیدونم ولی اگه اشتباه نکنم ، میانگین کلاک هسته ها میشه 3.5 و بنابراین باز هم اگه اشتباه نکنم ، هسته ها با کلاک های متفاوتی کار میکنند و در نتیجه ، وقتی یک پروسه رو اجرا میکنیم ، مقدار cpu usage اش 98 درصد میشه اما وقتی دو تا پروسه را اجرا میکنیم این مقدار در یک پروسه ، 94 و در پروسه ی دیگه 92 میشه .
البته اینی که کلاک هسته ها در پردازنده های دارای تکنولوژی turbo boost clock ، متفاوت خواهد بود یا نه را باید تحقیق بشه (من فعلا اینترنت بین الملل ندارم) ولی به احتمال بسیار زیاد (95 درصد) ، همینطور هست.

سوال اینه که چرا بازدهی اومد پایینتر، نه اینکه چرا رفت بالاتر. شما دارید میگید چون پردازنده Turbo Boost داره که در موقع نیاز به پردازش بیشتر، فرکانس عملیاتی پردازشگر رو موقتا میبره بالاتر و در نتیجه پردازنده سریعتر کار می کنه.
چون باید سریعتر کار کنه پس کندتر کار کرده؟ حالتون خوبه؟ :لبخند:
وقتی شما یک نخ رو به تنهایی اجرا می کردید یا این Turbo Boost فعال بوده یا نبوده. اگر در حالت تک نخی فعال بوده که در حالتی که با دو نخ کار می کردید هم فعال بوده و فرکانس کاری در بدترین شرایط همون بوده و تغییری نکرده، و در شرایط بهتر میتونسته حتی فرکانس بالاتر هم رفته باشه. اگر در حالت تک نخی Turbo Boost فعال نبوده، پس اگر در حالت دو نخی فعال شده که باید کارکرد بهتر هم بشه، چرا بدتر؟ تازه شما کل توان پردازنده رو که فعال نکردید، 50 درصدش ئه. Turbo Boost تسریع کننده است، تضعیف کننده که نیست.
شما دارید برای کاهش کارایی دلیلی میارید که کارش بهتر کردن کارایی است.



من اینم بگم قشنگ متوجه ی منظورتون نشدم ، قضیه ی مرغ را پیش نمیکشید :لبخند:


نه فعلا با قضیه Turbo Boost پیش میریم.



این هم مثل قضیه ی بالا (توربو کلاک) که گفتم .
البته شاید وقتی بین دو هسته میخواد سوئیچ بشه ، وقتی از حافظه ی مشترک بین تمام هسته های فیزیکی (که اگه اشتباه نکنم ، حافظه ی کش سطح l3 ، حافظه ی مشترک بین تمام هسته های فیزیکی هست . درسته؟) شاید نیاز داشته باشه که این دو هسته برای انتقال کارهاشون ازش استفاده کنن که در این صورت چون حافظه ی مشترک هست ، در یک لحظه ، فقط یک هسته قطعا میتونه ازش استفاده کنه و سایر هسته ها نمیتونن و سربار ایجاد کنه ولی غیر از این حالت ها منظورم بود .
شما می گید یک حافظه cache level 3 در بعضی پردازنده ها هست که بین همه هسته های فیزیکی مشترک هستند و هر کدوم بخواد ازش استفاده کنه بقیه هسته ها باید صبر کنند. اصلا کاری با درستی و نادرستی اش ندارم، با قابل قبول بودنش کار دارم.
با این فرض که دسترسی بهش بصورت همزمان میسر نیست، دارید میگید وقتی یک هسته بخواد کاری با این حافظه مشترک انجام بده، لازمه که چهار هسته دیگه صبر کنند؟
با این تعبیر که در هر لحظه فقط یک هسته از چهار هسته داره کاری با اون حافظه انجام میده و بقیه دارن صبر می کنند، چه با کد نخ شما درگیر باشن و چه نباشن.
به این مساله توجه دارید که پیش از دسترسی به حافظه اصلی RAM باید به این حافظه Cache رجوع بشه؟
Cache داخل CPU برای چیه؟ برای اینکه قبل از اینکه فرضا از حافظه اصلی چیزی خونده بشه بررسی بشه که آیا در این حافظه Cache گرانقیمت سریع کم حجم اون داده درخواستی هست که اگر باشه بجای حافظه اصلی از اون خونده بشه که کارایی بره بالا.
اون Cache اضافه شده تا سرعت رو بالاتر ببره. اگر قرار باشه هسته ها برای دسترسی شون به Cache تو صف وایستن که هم کارایی هر چهار هسته میاد پایین و هم دسترسی به حافظه کند میشه. نمیان که یک حافظه گرانقیمت و پیچیده رو قرار بدن که بجای کمک مشکل ایجاد کنه.

SajjadKhati
چهارشنبه 06 آذر 1398, 22:15 عصر
سوال اینه که چرا بازدهی اومد پایینتر، نه اینکه چرا رفت بالاتر. شما دارید میگید چون پردازنده Turbo Boost داره که در موقع نیاز به پردازش بیشتر، فرکانس عملیاتی پردازشگر رو موقتا میبره بالاتر و در نتیجه پردازنده سریعتر کار می کنه.



سلامی مجدد .
خیلی ممنون استاد .
نه . منظورم رو خوب متوجه نشدین . اتفاقا برعکسِ این قضیه رو گفتم .
بحث نیاز به پردازشِ بیشتر نیست . کلا پردازنده هایی که تکنولوژی turbo boost clock رو دارن ، هر چی کارکرد و فشار کاریِ پردازنده بیشتر بشه ، کلاک شون پایین تر میاد (نه اینکه بالاتر بره) تا جایی که کلاک شون به کلاک پایه ی پردازنده نزدیک بشه .و برعکسش ، هر چی بار کاری شون کمتر باشه ، فرکانس اش افزایش پیدا میکنه تا جایی که به کلاک turbo boost اش نزدیک تر بشه .
یا به عبارتی دیگه ، بالاترین فرکانس را در صورتی دارن که (معمولا) فقط به اندازه ی یک هسته اش درگیر فعالیت باشه .



چون باید سریعتر کار کنه پس کندتر کار کرده؟ حالتون خوبه؟ :لبخند:
وقتی شما یک نخ رو به تنهایی اجرا می کردید یا این Turbo Boost فعال بوده یا نبوده. اگر در حالت تک نخی فعال بوده که در حالتی که با دو نخ کار می کردید هم فعال بوده و فرکانس کاری در بدترین شرایط همون بوده و تغییری نکرده، و در شرایط بهتر میتونسته حتی فرکانس بالاتر هم رفته باشه. اگر در حالت تک نخی Turbo Boost فعال نبوده، پس اگر در حالت دو نخی فعال شده که باید کارکرد بهتر هم بشه، چرا بدتر؟ تازه شما کل توان پردازنده رو که فعال نکردید، 50 درصدش ئه. Turbo Boost تسریع کننده است، تضعیف کننده که نیست.
شما دارید برای کاهش کارایی دلیلی میارید که کارش بهتر کردن کارایی است.


بنابراین در پردازنده ی من (که فرکانس پایه اش 3.2 و فرکانس turbo boost اش 3.4 هست) ، وقتی یک برنامه (یک پروسه با یک نخ) را اجرا میکنم ، فقط یک هسته یعنی 25 درصد را اشغال میکنه (البته 5 تا 10 درصد هم بقیه ی پروسه ها و نخ هاشون پردازش میخوان که کلا میشه 30 تا 35 درصد پردازنده اشغال میشه) که در این صورت ، فرکانس پردازنده بین 3.33 تا 3.35 گیگاهرتز هست (این ، همونی هه که cpu usage اش 98 درصد بود) .

اما وقتی دو تا برنامه (پروسه) باز میکنم که هر کدوم شون یک نخ را اجرا میکنن یا اینکه یک برنامه با دو نخ را اجرا میکنم که در هر کدوم از این دو حالت ، 50 درصد از توان پردازنده مصرف میشه (البته 5 تا 10 درصد هم بقیه ی پروسه ها و نخ هاشون پردازش میخوان که کلا میشه 55 تا 60 درصد پردازنده اشغال میشه) ، طبق همون قضیه ی turbo boost که گفتم ، چون بار کاری و درصد استفاده ی پردازنده بالاتر رفت ، فرکانس اش کمتر میشه (تا به فرکانس پایه ی پردازنده ، نزدیک و نزدیک تر بشه) و در این میزان از بار کاری (بار کاری 55 تا 60 درصد) ، فرکانس پردازنده ام بین 3.23 تا 3.25 هست . (همونطور که گفتم ، نمیدونم میانگین فرکانس همه ی هسته ها این مقدار میشه یا فرکانس همه ی هسته ها همین فرکانسی که اعلام میکنه هست . اما فکر کنم میانگین شون باشه . باز هم دقیق نمیدونم) بنابراین در این حالت ، عملکرد هسته هام کاهش پیدا میکنه (به نسبت تک پروسه ی قبلی که فرکانسش 3.33 تا 3.35 بود) (این ، همونی هه که یه پروسه ، cpu usage اش 94 و یه پروسه ی دیگه ، cpu usage اش 92 درصد شده بود) .


الان ، اغلب پردازنده های روز ، turbo boost رو دارن . فلسفه اش هم اینه که این تکنولوژی اومد تا عملکرد تک هسته ای رو بالاتر ببره . حالا واسه ی من اختلاف کلاک پایه و کلاک بوست پردازنده ام 200 مگاهرتز هه اما پردازنده های روز ، اختلاف شون به 400 مگاهرتز و گاها تا 1 گیگاهرتز (و حتی گاها بیشتر) میرسه .
توی لپتاپ تاپ ها ، اختلاف کلاک پایه و کلاک بوست ، معمولا زیاد هه . به احتمال بسیار زیاد ، پردازنده ی شما هم این قابلیت را داره (البته من اینترنت بین الملل ندارم نمیتونم تحقیق کنم) .
استاد ، شما همین برنامه ای رو که نوشتین رو اجرا کنین . اول یکی نخ بسازید و در task manager در سربرگ performance اش ببینین کلاک (speed) اش چقدره . بعد دوباره دو نخ را پشت سر هم اجرا کنین و ببینین این بار چقدره . و همین جوری تا 8 نخ پشت سر هم اجرا کنین . اگه دیدین هر بار که نخ های بیشتری ایجاد میکنین (و کلا بار کاری و درصد اشغال پردازنده تون بیشتر میشه) ، کلاک تون پایین تر میاد ، پردازنده تون از turbo boost پشتیبانی میکنه . البته قابلیت turbo boost ، باید در بایوس (یا uefi) تون هم فعال شده باشه .



نه فعلا با قضیه Turbo Boost پیش میریم.


شما می گید یک حافظه cache level 3 در بعضی پردازنده ها هست که بین همه هسته های فیزیکی مشترک هستند و هر کدوم بخواد ازش استفاده کنه بقیه هسته ها باید صبر کنند. اصلا کاری با درستی و نادرستی اش ندارم، با قابل قبول بودنش کار دارم.
با این فرض که دسترسی بهش بصورت همزمان میسر نیست، دارید میگید وقتی یک هسته بخواد کاری با این حافظه مشترک انجام بده، لازمه که چهار هسته دیگه صبر کنند؟
با این تعبیر که در هر لحظه فقط یک هسته از چهار هسته داره کاری با اون حافظه انجام میده و بقیه دارن صبر می کنند، چه با کد نخ شما درگیر باشن و چه نباشن.
به این مساله توجه دارید که پیش از دسترسی به حافظه اصلی RAM باید به این حافظه Cache رجوع بشه؟
Cache داخل CPU برای چیه؟ برای اینکه قبل از اینکه فرضا از حافظه اصلی چیزی خونده بشه بررسی بشه که آیا در این حافظه Cache گرانقیمت سریع کم حجم اون داده درخواستی هست که اگر باشه بجای حافظه اصلی از اون خونده بشه که کارایی بره بالا.
اون Cache اضافه شده تا سرعت رو بالاتر ببره. اگر قرار باشه هسته ها برای دسترسی شون به Cache تو صف وایستن که هم کارایی هر چهار هسته میاد پایین و هم دسترسی به حافظه کند میشه. نمیان که یک حافظه گرانقیمت و پیچیده رو قرار بدن که بجای کمک مشکل ایجاد کنه.



منظورم را دقیق متوجه نشدین . درباره ی این قضیه ، چیز خاصی نمیدونم . واسه ی همین گفتم شاید کش l3 مشترک باشه در همه ی هسته های فیزیکی . (نمیدونم دقیق) . در صورت صحت ، باز هم منظورم برای یه قضیه ی دیگه یعنی لحظه ی سوئیچ نخ پروسه مون بین دو هسته ی فیزیکی مختلف بود (که داشتیم درباره اش صحبت میکردیم) . به هر حال گفتم که ، این قضیه ی کش l3 که گفتم ، یه چیز علمی و مستند نبود و اطلاع کافی ندارم واسه ی همین گفتم شاید . کلا بگذریم .


اما استاد ، وقتی که اطلاعات نخ (که متوقف شده بود) و (وضعیت اش) در هسته ی فیزیکی ای در رجیستر ثبت شده بود ، حالا قراره به هسته ی فیزیکی دیگه ای پاس داده بشه ، نیاز داره که اطلاعات اون نخ که در رجیستری ثبت شده ، اول به حافظه ای مشترک بین این هسته های فیزیکی منتقل بشه و بعد به حافظه ی رجیستریِ هسته ی فیزیکی جدید برای ادامه ی عملیات و اجرای نخ ، منتقل بشه دیگه . درسته؟ (حافظه ی کش l3 هم کلا مشترک هست بین تمام هسته های فیزیکی دیگه . درسته؟)

the king
پنج شنبه 07 آذر 1398, 14:46 عصر
سلامی مجدد .
خیلی ممنون استاد .
نه . منظورم رو خوب متوجه نشدین . اتفاقا برعکسِ این قضیه رو گفتم .
بحث نیاز به پردازشِ بیشتر نیست . کلا پردازنده هایی که تکنولوژی turbo boost clock رو دارن ، هر چی کارکرد و فشار کاریِ پردازنده بیشتر بشه ، کلاک شون پایین تر میاد (نه اینکه بالاتر بره) تا جایی که کلاک شون به کلاک پایه ی پردازنده نزدیک بشه .و برعکسش ، هر چی بار کاری شون کمتر باشه ، فرکانس اش افزایش پیدا میکنه تا جایی که به کلاک turbo boost اش نزدیک تر بشه .

پس بنظرتون اینتل در توضیحات Intel Turbo Boost اشتباه می کنه که میگه وقتی بار کاری کاربر از پردازنده درخواست کارایی بالاتر می کنه فرکانس رو بالاتر از حد عادی میبره؟ شما دارید درست عکس چیزی رو میگید که Intel از تکنولوژی اش توصیف میکنه.
بعد به نظرتون این بالا بردن فرکانس کاری پردازنده وقتی فشار کاری روی اون نیست با چه هدفیه؟ افزایش مصرف برق؟ کاهش عمر پردازنده؟ افزایش اتلاف حرارتی؟ یا همه شون؟ وقتی بار کاری خاصی روی پردازنده نیست که نیازی به کارایی و فرکانس پردازش بالاتری نداریم، برای چی فرکانس رو ببریم بالاتر؟


When the processor is operating below these limits and the user's workload demands additional performance, the processor frequency will dynamically increase until the upper limit of frequency is reached. Intel® Turbo Boost Technology 2.0 has multiple algorith

https://www.intel.com/content/www/us/en/architecture-and-technology/turbo-boost/turbo-boost-technology.html



یا به عبارتی دیگه ، بالاترین فرکانس را در صورتی دارن که (معمولا) فقط به اندازه ی یک هسته اش درگیر فعالیت باشه .

این مطلب رو در کجا خوندید؟ منبعش کجا است؟



بنابراین در پردازنده ی من (که فرکانس پایه اش 3.2 و فرکانس turbo boost اش 3.4 هست) ، وقتی یک برنامه (یک پروسه با یک نخ) را اجرا میکنم ، فقط یک هسته یعنی 25 درصد را اشغال میکنه (البته 5 تا 10 درصد هم بقیه ی پروسه ها و نخ هاشون پردازش میخوان که کلا میشه 30 تا 35 درصد پردازنده اشغال میشه) که در این صورت ، فرکانس پردازنده بین 3.33 تا 3.35 گیگاهرتز هست (این ، همونی هه که cpu usage اش 98 درصد بود) .

اما وقتی دو تا برنامه (پروسه) باز میکنم که هر کدوم شون یک نخ را اجرا میکنن یا اینکه یک برنامه با دو نخ را اجرا میکنم که در هر کدوم از این دو حالت ، 50 درصد از توان پردازنده مصرف میشه (البته 5 تا 10 درصد هم بقیه ی پروسه ها و نخ هاشون پردازش میخوان که کلا میشه 55 تا 60 درصد پردازنده اشغال میشه) ، طبق همون قضیه ی turbo boost که گفتم ، چون بار کاری و درصد استفاده ی پردازنده بالاتر رفت ، فرکانس اش کمتر میشه (تا به فرکانس پایه ی پردازنده ، نزدیک و نزدیک تر بشه) و در این میزان از بار کاری (بار کاری 55 تا 60 درصد) ، فرکانس پردازنده ام بین 3.23 تا 3.25 هست . (همونطور که گفتم ، نمیدونم میانگین فرکانس همه ی هسته ها این مقدار میشه یا فرکانس همه ی هسته ها همین فرکانسی که اعلام میکنه هست . اما فکر کنم میانگین شون باشه . باز هم دقیق نمیدونم) بنابراین در این حالت ، عملکرد هسته هام کاهش پیدا میکنه (به نسبت تک پروسه ی قبلی که فرکانسش 3.33 تا 3.35 بود) (این ، همونی هه که یه پروسه ، cpu usage اش 94 و یه پروسه ی دیگه ، cpu usage اش 92 درصد شده بود) .

عملکرد Turbo Boost برای همه هسته ها یکسانه :


Is turbo frequency the same for all active cores in the processor?
Yes.




الان ، اغلب پردازنده های روز ، turbo boost رو دارن . فلسفه اش هم اینه که این تکنولوژی اومد تا عملکرد تک هسته ای رو بالاتر ببره . حالا واسه ی من اختلاف کلاک پایه و کلاک بوست پردازنده ام 200 مگاهرتز هه اما پردازنده های روز ، اختلاف شون به 400 مگاهرتز و گاها تا 1 گیگاهرتز (و حتی گاها بیشتر) میرسه .

توی لپتاپ تاپ ها ، اختلاف کلاک پایه و کلاک بوست ، معمولا زیاد هه . به احتمال بسیار زیاد ، پردازنده ی شما هم این قابلیت را داره (البته من اینترنت بین الملل ندارم نمیتونم تحقیق کنم) .
استاد ، شما همین برنامه ای رو که نوشتین رو اجرا کنین . اول یکی نخ بسازید و در task manager در سربرگ performance اش ببینین کلاک (speed) اش چقدره . بعد دوباره دو نخ را پشت سر هم اجرا کنین و ببینین این بار چقدره . و همین جوری تا 8 نخ پشت سر هم اجرا کنین . اگه دیدین هر بار که نخ های بیشتری ایجاد میکنین (و کلا بار کاری و درصد اشغال پردازنده تون بیشتر میشه) ، کلاک تون پایین تر میاد ، پردازنده تون از turbo boost پشتیبانی میکنه . البته قابلیت turbo boost ، باید در بایوس (یا uefi) تون هم فعال شده باشه .

خیر. تمامی هسته های پردازنده لپ تاپ من همواره در حالت عادی 2.4GHz میمونند و به 3.4GHz حداکثری Max Turbo شون نمی رسند، چه فشار کاری روشون باشه و چه نباشه، چون اصلا تنظیم Turbo Boost در BIOS اش وجود نداره که بخواد فعالش کنه.
اما شما که مدعی هستید عملکرد Turbo Boost منجر به تفاوت بازدهی هسته ها شده، می توانید در سیستم خودتون غیر فعالش کنید و ببینید که کاهش عملکرد دو نخ در دو برنامه مجزا نسبت به حالتی که یک نخ به تنهایی اجرا می شد ربطی به Turbo Boost نداره و وقتی Turbo Boost رو غیر فعال هم می کنید همچنان همین مساله هست.




اما استاد ، وقتی که اطلاعات نخ (که متوقف شده بود) و (وضعیت اش) در هسته ی فیزیکی ای در رجیستر ثبت شده بود ، حالا قراره به هسته ی فیزیکی دیگه ای پاس داده بشه ، نیاز داره که اطلاعات اون نخ که در رجیستری ثبت شده ، اول به حافظه ای مشترک بین این هسته های فیزیکی منتقل بشه و بعد به حافظه ی رجیستریِ هسته ی فیزیکی جدید برای ادامه ی عملیات و اجرای نخ ، منتقل بشه دیگه . درسته؟ (حافظه ی کش l3 هم کلا مشترک هست بین تمام هسته های فیزیکی دیگه . درسته؟)
جواب این سوال بله و خیر نیست. در هر پردازنده ای شرایط متفاوتی میتونه باشه، شاید اصلا Cache Level 3 نداشته باشه یا Cache Level 5 مشترک داشته باشه.
اصولا در سیستمی با پاسخگویی بلادرنگ که معماری خاص خودش رو هم داره از هر وقفه ای در اجرای نخ اجتناب می کنند، اما حالا فرض کنیم یک هسته شون خیلی داغ شده و ناچار به سوئیچ شدن، اگر قراره سوئیچی صورت بگیره همون لحظه و بدون وقفه از پردازنده فلان به به بهمان منتقل میشه و مشابه گفته شما از نزدیکترین و سریعترین حافظه مشترک بین شون استفاده میشه. همچین چیزی مثلا برای جاهایی که روی زمان حساسیت زیاد ئه، فرضا سیستم های هدایت هواپیما کاربرد داره.

ولی در سیستم عامل متعارفی مثل ویندوز که اینقدر پاسخگویی به نخ بلادرنگ نیست، که نخ از این هسته فوری بپره به یک هسته دیگه. اگر نخ تون در این هسته اجراش تموم شده تا اجرای بعدیش وقفه ایجاد میشه. لزومی نداره که وضعیتش در Cache مشترک جابجا بشه.
سوئیچ کردن یک عملیاتی است با نظارت سیستم عامل و یکسری عملیات اضافی هم داره که سربار میشه ولی نیاز پردازنده نیست، مربوط به کارکرد سیستم عامل ئه. در اینجور سوئیچ ها از یک هسته فیزیکی به یک هسته فیزیکی دیگه همینطور درجا و بدون وقفه نیست.
اول نخ متوقف میشه، وضعیت اجرایی اش به حافظه اصلی منتقل میشه، ممکنه دز حافظه Cache مشترک باقی بمونه ولی شاید جایگزین بشه و برای استفاده اون یکی هسته باقی نمونه.
چه بسا مدت کوتاهی حتی فرصت اجرا در اون یکی هسته بهش داده نشه. وقتی هم که نوبت اجرا در هسته دیگه بهش رسید مرجع نهایی همچنان حافظه اصلی است که حتی شاید در اون هم نباشه و در انتها به حافظه مجازی روی دیسک رجوع بشه.
در نظر بگیرید که فرضا یک پردازنده با 6 مگابایت Cache مشترک نمی تونه مدت طولانی چیزی رو داخلش نگه داره.

SajjadKhati
پنج شنبه 07 آذر 1398, 19:23 عصر
پس بنظرتون اینتل در توضیحات Intel Turbo Boost اشتباه می کنه که میگه وقتی بار کاری کاربر از پردازنده درخواست کارایی بالاتر می کنه فرکانس رو بالاتر از حد عادی میبره؟ شما دارید درست عکس چیزی رو میگید که Intel از تکنولوژی اش توصیف میکنه.
بعد به نظرتون این بالا بردن فرکانس کاری پردازنده وقتی فشار کاری روی اون نیست با چه هدفیه؟ افزایش مصرف برق؟ کاهش عمر پردازنده؟ افزایش اتلاف حرارتی؟ یا همه شون؟ وقتی بار کاری خاصی روی پردازنده نیست که نیازی به کارایی و فرکانس پردازش بالاتری نداریم، برای چی فرکانس رو ببریم بالاتر؟



When the processor is operating below these limits and the user's workload demands additional performance, the processor frequency will dynamically increase until the upper limit of frequency is reached. Intel® Turbo Boost Technology 2.0 has multiple algorith



https://www.intel.com/content/www/us/en/architecture-and-technology/turbo-boost/turbo-boost-technology.html


سلامی مجدد
خیلی ممنون استاد .
من به اینترنت بین الملل دسترسی ندارم . نمیتونم این مطالب را تحقیق کنم .
بنابراین نمیدونم منظور از these limits در جمله ی بالا ، کدوم محدودیت را میگه . همچنین ممکنه این مطلب ادامه داشته باشه و همچنین مطالب و مقالات دیگه وجود داشته باشه که من فعلا اینترنت ندارم که تحقیق کنم .
ضمن اینکه همونطور که گفت ، این تکنولوژی چندین نسخه اش اومد . این هم میگه الگوریتم های مختلف میتونن داشته باشن . مثلا درباره ی پردازنده ی Ryzen 3600 (که پردازنده ی جدیدی هم هست) ، فرکانس پایه اش 3.6 و فرکانس turbo boost اش 4.2 هست . اگه اشتباه نکنم در این پردازنده ، حتی اگه همه ی هسته هاش با تمام توانشون فعال باشن ، باز هم کلاک اش ، بیشتر (شاید هم خیلی بیشتر) از کلاک فرکانس پایه اش هست . (در این مورد ، دقیق نمیدونم . گفتم شاید) . کلا میگم که بستگی به پردازنده اش و همونطور که نوشته ، الگوریتم هاش داره . بنابراین ممکنه پردازنده ای باشه که با افزایش بار کاریش ، فرکانسش کم نشه .






این مطلب رو در کجا خوندید؟ منبعش کجا است؟


ولی در اینکه پایه ی این قضیه ، همین ای هست که (در پست قبل) بهتون گفتم ، شک ندارم .
فعلا هم اینترنت (بین الملل) ندارم که براتون لینکی یا چیزی بذارم (وگرنه همون انجمن میامدم خودم ها :لبخند: ) ولی اگه شک دارین ، اولا من خودم این قضیه رو دارم میبینم (که با افزایش بار کاری پردازنده ام ، فرکانسش کمتر میشه تا به فرکانس پایه میرسه) و دوما همین چک کردن نرم افزار را که گفتین انجام دادم که در زیر ، گزارش اش را میدم و سوما اگه سئوال تون اینه که از کجا میدونم ، مباحث سخت افزاری رو یه کم پی گیری میکنم و چهارما دیگه اگه حرفم را قبول ندارین ، میتونین از بچه های سخت افزار و کسانی که توی سخت افزار علم دارن ، این موضوع را هم بپرسین . یا من تاپیک بزنم و بپرسم و بهتون لینک اون تاپیک رو بدم تا جواب رو نگاه کنین (اگه مایلید ، بگین) . چون به هر حال من فعلا اینترنت ندارم.



عملکرد Turbo Boost برای همه هسته ها یکسانه :


دقیق در این باره خبر ندارم ولی گمان نکنم.
چون الان توی بایوس ام که رفته بودم ، وقتی turbo boost را که فعال کنم ، زیرش لیست هر هسته (کلا 4 هسته) میاد و جلوی هر کدوم ، فرکانس شون را مینویسه (نه اینکه مثلا یک هسته ی خاص را مشخص کنه و مثلا بگه هسته ی 0 فرکانس اش فلان هه . بلکه فرکانس یکی از هسته ها رو میگه که فلان فرکانس رو داره) . یعنی برام این جوری نوشته بود (دقیق جملاتش را حضور ذهن ندارم ولی کلا همین بود) :

turbo boost core 3.4Ghz
turbo boost core 3.3Ghz
turbo boost core 3.2Ghz
turbo boost core 3.2Ghz

اینها بصورت پیش فرض بودن که میشد تغییر هم داد ولی نمیدونم تغییرات اعمال بشه یا نه . چون تغییراتش (افزایش فرکانس اش) ، احتمالا اورکلاک حساب میشه و مادربردم سری H هست که اورکلاک را ساپورت نمیکنه (البته بعضی ها میگن میکنه که نمیدونم) . مادربرد سری Z اورکلاک را ساپورت میکنه . (برای اورکلاک هم خود پردازنده هم فکر کنم باید سری K را داشته باشه . این معمولی ها فکر نکنم بشه) . به هر حال ، تنظیمات کلاک پیش فرض اش را تا حالا دست نزدم .




خیر. تمامی هسته های پردازنده لپ تاپ من همواره در حالت عادی 2.4GHz میمونند و به 3.4GHz حداکثری Max Turbo شون نمی رسند، چه فشار کاری روشون باشه و چه نباشه، چون اصلا تنظیم Turbo Boost در BIOS اش وجود نداره که بخواد فعالش کنه.


مطمئنید در بایوس تون همچین تنظیماتی نیست؟
اولا اینکه پردازنده تون پشتیبانی میکنه؟ اگه بکنه ، به احتمالا بسیار زیاد ، توی تنظیمات بایوس لپتاپ تون باید همچین گزینه ای باشه .
مثلا واسه ی من در بایوس مادربرد (uefi) ، در قسمت M.I.T و بعد در قسمت advanced frequency cpu و بعد turbo boost clock بود .
اگه همچین گزینه ای را در بایوس تون ندیدین ، ببینین بایوس تون چه پروفایل هایی داره . مثلا بجز default profile ، پروفایل دیگه ای هم شاید داشته باشه که اگه اون را فعال کنین ، خودش turbo boost clock رو فعال کنه .





اما شما که مدعی هستید عملکرد Turbo Boost منجر به تفاوت بازدهی هسته ها شده، می توانید در سیستم خودتون غیر فعالش کنید و ببینید که کاهش عملکرد دو نخ در دو برنامه مجزا نسبت به حالتی که یک نخ به تنهایی اجرا می شد ربطی به Turbo Boost نداره و وقتی Turbo Boost رو غیر فعال هم می کنید همچنان همین مساله هست.


بله این کار را کردم که گزارش را میدم .
اول این رو بگم که در هر دو حالت (با فعال کردن و غیرفعال کردن Turbo Boost) ، برنامه ی شما ، در حالت های مختلف (یک نخی در یک پروسه و تک نخی در دو پروسه . دو نخی در یک پروسه و دو نخی در دو پروسه) ، هیچ فرقی با گزارش هایی که قبلا دادم ، نکرد . من فکر میکردم مقدار cpu usage در برنامه ی شما ، سرعت پردازش را میده اما اگه اشتباه نکنم ، مقدار این رو میده که یک هسته چند درصدش فعال بود (درسته؟) . یعنی سرعت پردازش نخ را نمیسنجه پس فرکانس برای اون هسته ، چه بالا باشه یا پایین ، فرقی به آمارش نداره .




بنابراین برای سنجش سرعت پردازش نخ ام ، همون الگوریتم ساده ی خودم (حلقه ی for) را استفاده کردم (کد اول درپست اول) .
دو کد زیر ، دو تابع اصلی اش هستن :



private void SingleThread()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();


for (long i = 0; i < 10000000000; i++)
{
}


stopwatch.Stop();
long elapsed = stopwatch.ElapsedMilliseconds;
MessageBox.Show("elspsed : " + elapsed.ToString() + " ms", "Main Thread");
}



private void NewThreadMethod_1()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();


for (long counter = 0; counter < 10000000000; counter++)
{
}


stopwatch.Stop();
long elapsed = stopwatch.ElapsedMilliseconds;
MessageBox.Show("elspsed : " + elapsed.ToString() + " ms", "New Thread");
}




و در 4 دکمه ، که در هر کدوم ، یه نخ براش اضافه میکردم .
یعنی در دکمه ی اول ، کد :



private void TcSingleThread_Click(object sender, EventArgs e)
{
this.SingleThread();
}



و در دکمه ی دوم ، کد :



private void TcDualThread_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(this.NewThreadMethod_1));
thread.Start();


this.SingleThread();
}




و در دکمه ی سوم ، کد :



private void TcThreeThread_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(this.NewThreadMethod_1));
thread.Start();


Thread thread_2 = new Thread(new ThreadStart(this.NewThreadMethod_1));
thread_2.Start();




this.SingleThread();
}



و در دکمه ی چهارم ، کد :



private void TcFourThread_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(this.NewThreadMethod_1));
thread.Start();


Thread thread_2 = new Thread(new ThreadStart(this.NewThreadMethod_1));
thread_2.Start();


Thread thread_3 = new Thread(new ThreadStart(this.NewThreadMethod_1));
thread_3.Start();




this.SingleThread();
}



را گذاشتم .




Turbo Boost Clock را غیر فعال کردم (یعنی پردازنده ام با فرکانس 3.18 تا 3.19 فقط کار میکرد) :

1 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151045&stc=1


2 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151046&stc=1


3 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151047&stc=1


4نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151048&stc=1


1 نخ در 2 پروسه (کلا 2 نخ) :

https://barnamenevis.org/attachment.php?attachmentid=151049&stc=1


2 نخ در 2 پروسه (کلا 4 نخ) :

چون در یک پست ، بیشتر از 5 عکس رو نمیشه قرار داد ، ادامه را در دو پست بعدی میذارم ....





جواب این سوال بله و خیر نیست. در هر پردازنده ای شرایط متفاوتی میتونه باشه، شاید اصلا Cache Level 3 نداشته باشه یا Cache Level 5 مشترک داشته باشه.
اصولا در سیستمی با پاسخگویی بلادرنگ که معماری خاص خودش رو هم داره از هر وقفه ای در اجرای نخ اجتناب می کنند، اما حالا فرض کنیم یک هسته شون خیلی داغ شده و ناچار به سوئیچ شدن، اگر قراره سوئیچی صورت بگیره همون لحظه و بدون وقفه از پردازنده فلان به به بهمان منتقل میشه و مشابه گفته شما از نزدیکترین و سریعترین حافظه مشترک بین شون استفاده میشه. همچین چیزی مثلا برای جاهایی که روی زمان حساسیت زیاد ئه، فرضا سیستم های هدایت هواپیما کاربرد داره.

ولی در سیستم عامل متعارفی مثل ویندوز که اینقدر پاسخگویی به نخ بلادرنگ نیست، که نخ از این هسته فوری بپره به یک هسته دیگه. اگر نخ تون در این هسته اجراش تموم شده تا اجرای بعدیش وقفه ایجاد میشه. لزومی نداره که وضعیتش در Cache مشترک جابجا بشه.
سوئیچ کردن یک عملیاتی است با نظارت سیستم عامل و یکسری عملیات اضافی هم داره که سربار میشه ولی نیاز پردازنده نیست، مربوط به کارکرد سیستم عامل ئه. در اینجور سوئیچ ها از یک هسته فیزیکی به یک هسته فیزیکی دیگه همینطور درجا و بدون وقفه نیست.
اول نخ متوقف میشه، وضعیت اجرایی اش به حافظه اصلی منتقل میشه، ممکنه دز حافظه Cache مشترک باقی بمونه ولی شاید جایگزین بشه و برای استفاده اون یکی هسته باقی نمونه.
چه بسا مدت کوتاهی حتی فرصت اجرا در اون یکی هسته بهش داده نشه. وقتی هم که نوبت اجرا در هسته دیگه بهش رسید مرجع نهایی همچنان حافظه اصلی است که حتی شاید در اون هم نباشه و در انتها به حافظه مجازی روی دیسک رجوع بشه.
در نظر بگیرید که فرضا یک پردازنده با 6 مگابایت Cache مشترک نمی تونه مدت طولانی چیزی رو داخلش نگه داره.


خیلی ممنون استاد .

SajjadKhati
پنج شنبه 07 آذر 1398, 19:34 عصر
ادامه :

2 نخ در 2 پروسه (کلا 4 نخ) :

https://barnamenevis.org/attachment.php?attachmentid=151050&stc=1


Turbo Boost Clock را فعال کردم (یعنی پردازنده ام با فرکانس 3.18 تا 3.38 ، بصورت متغییر کار میکرد) :

1 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151051&stc=1


2 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151053&stc=1


3 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151054&stc=1


4 نخ در 1 پروسه :

https://barnamenevis.org/attachment.php?attachmentid=151055&stc=1


ادامه در پست بعدی ... .

SajjadKhati
پنج شنبه 07 آذر 1398, 20:06 عصر
ادامه :

Turbo Boost Clock را فعال کردم (یعنی پردازنده ام با فرکانس 3.18 تا 3.38 ، بصورت متغییر کار میکرد) :

1 نخ در 2 پروسه (کلا 2 نخ) :

https://barnamenevis.org/attachment.php?attachmentid=151056&stc=1



2 نخ در 2 پروسه (کلا 4 نخ) :

https://barnamenevis.org/attachment.php?attachmentid=151057&stc=1




در 1 نخ در 1 پروسه ، هم برای وقتی که Turbo Boost Clock فعال هست (نتیجه ی زمان اجرای کد ،23.519 ثانیه شد) (در این حالت ، میانگین کلاک پردازنده بین 3.33 تا 3.35 بود که حالا هی بالا و پایین تر میرفت اما میانگین اش این بود) و هم در زمانی که Turbo Boost Clock غیر فعال هست (نتیجه ی زمان اجرای کد ، 24.687 ثانیه شد) (در این حالت ، کلاک پردازنده ، 3.19 بود) را مقایسه کنید ، میبینید که اختلاف کلاک ها ، تقریبا 100 مگاهرتز ، یعنی تقریبا 1.047 برابر ، کلاک شون با هم اختلاف داشت و تفاوت زمانی شون هم 1.048 برابر هست .

بجز این ، تفاوت را بیشتر در پردازنده هایی بهتر میشه متوجه شد که اختلاف turbo boost clock و کلاک پایه شون ، زیاد و زیادتر باشه (حداقل 400 مگاهرتز یا بیشتر) . معمولا لپتاپ ها اختلاف شون خیلی زیاد تر هه .

the king
پنج شنبه 07 آذر 1398, 20:41 عصر
سلامی مجدد
خیلی ممنون استاد .
من به اینترنت بین الملل دسترسی ندارم . نمیتونم این مطالب را تحقیق کنم .

بنابراین نمیدونم منظور از these limits در جمله ی بالا ، کدوم محدودیت را میگه . همچنین ممکنه این مطلب ادامه داشته باشه و همچنین مطالب و مقالات دیگه وجود داشته باشه که من فعلا اینترنت ندارم که تحقیق کنم .
ضمن اینکه همونطور که گفت ، این تکنولوژی چندین نسخه اش اومد . این هم میگه الگوریتم های مختلف میتونن داشته باشن . مثلا درباره ی پردازنده ی Ryzen 3600 (که پردازنده ی جدیدی هم هست) ، فرکانس پایه اش 3.6 و فرکانس turbo boost اش 4.2 هست . اگه اشتباه نکنم در این پردازنده ، حتی اگه همه ی هسته هاش با تمام توانشون فعال باشن ، باز هم کلاک اش ، بیشتر (شاید هم خیلی بیشتر) از کلاک فرکانس پایه اش هست . (در این مورد ، دقیق نمیدونم . گفتم شاید) . کلا میگم که بستگی به پردازنده اش و همونطور که نوشته ، الگوریتم هاش داره . بنابراین ممکنه پردازنده ای باشه که با افزایش بار کاریش ، فرکانسش کم نشه .

ولی در اینکه پایه ی این قضیه ، همین ای هست که (در پست قبل) بهتون گفتم ، شک ندارم .
فعلا هم اینترنت (بین الملل) ندارم که براتون لینکی یا چیزی بذارم (وگرنه همون انجمن میامدم خودم ها :لبخند: ) ولی اگه شک دارین ، اولا من خودم این قضیه رو دارم میبینم (که با افزایش بار کاری پردازنده ام ، فرکانسش کمتر میشه تا به فرکانس پایه میرسه) و دوما همین چک کردن نرم افزار را که گفتین انجام دادم که در زیر ، گزارش اش را میدم و سوما اگه سئوال تون اینه که از کجا میدونم ، مباحث سخت افزاری رو یه کم پی گیری میکنم و چهارما دیگه اگه حرفم را قبول ندارین ، میتونین از بچه های سخت افزار و کسانی که توی سخت افزار علم دارن ، این موضوع را هم بپرسین . یا من تاپیک بزنم و بپرسم و بهتون لینک اون تاپیک رو بدم تا جواب رو نگاه کنین (اگه مایلید ، بگین) . چون به هر حال من فعلا اینترنت ندارم.

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



دقیق در این باره خبر ندارم ولی گمان نکنم.

بله شما درست میگید، لابد اینتل داره اشتباه میگه. من عین متن سوال و جواب رو از FAQ اینتل نقل قول کردم :
https://www.intel.com/content/www/us/en/support/articles/000007359/processors/intel-core-processors.html
که متن کاملش رو هم پیوست همین پست کردم.



چون الان توی بایوس ام که رفته بودم ، وقتی turbo boost را که فعال کنم ، زیرش لیست هر هسته (کلا 4 هسته) میاد و جلوی هر کدوم ، فرکانس شون را مینویسه (نه اینکه مثلا یک هسته ی خاص را مشخص کنه و مثلا بگه هسته ی 0 فرکانس اش فلان هه . بلکه فرکانس یکی از هسته ها رو میگه که فلان فرکانس رو داره) . یعنی برام این جوری نوشته بود (دقیق جملاتش را حضور ذهن ندارم ولی کلا همین بود) :

turbo boost core 3.4Ghz
turbo boost core 3.3Ghz
turbo boost core 3.2Ghz
turbo boost core 3.2Ghz

اینها بصورت پیش فرض بودن که میشد تغییر هم داد ولی نمیدونم تغییرات اعمال بشه یا نه . چون تغییراتش (افزایش فرکانس اش) ، احتمالا اورکلاک حساب میشه و مادربردم سری H هست که اورکلاک را ساپورت نمیکنه (البته بعضی ها میگن میکنه که نمیدونم) . مادربرد سری Z اورکلاک را ساپورت میکنه . (برای اورکلاک هم خود پردازنده هم فکر کنم باید سری K را داشته باشه . این معمولی ها فکر نکنم بشه) . به هر حال ، تنظیمات کلاک پیش فرض اش را تا حالا دست نزدم .

مطمئنید در بایوس تون همچین تنظیماتی نیست؟
اولا اینکه پردازنده تون پشتیبانی میکنه؟ اگه بکنه ، به احتمالا بسیار زیاد ، توی تنظیمات بایوس لپتاپ تون باید همچین گزینه ای باشه .

بله. اصلا مورد عجیبی نیست. خیلی عادیه. سازنده لپ تاپ با توجه به توان تغذیه باطری و سیستم خنک کننده ای که بکار برده ممکنه ببینه نمیتونه از عهده تامین انرژی و حرارت فرکانس بالاتر پردازنده بربیاد و در نتیجه ترجیح بده غیر فعال نگهش داره.



مثلا واسه ی من در بایوس مادربرد (uefi) ، در قسمت M.I.T و بعد در قسمت advanced frequency cpu و بعد turbo boost clock بود .
اگه همچین گزینه ای را در بایوس تون ندیدین ، ببینین بایوس تون چه پروفایل هایی داره . مثلا بجز default profile ، پروفایل دیگه ای هم شاید داشته باشه که اگه اون را فعال کنین ، خودش turbo boost clock رو فعال کنه .

من هم دونه به دونه گزینه های BIOS سیستم ام رو میشناسم و هم با انواع مختلف BIOS ها کار کردم.
گمان نمی کنم کسی که برای تغییر تنظیمات BIOS برنامه اسمبلی مینوشته برای اینکه تشخیص بده یک مورد ساده ای مثل Turbo Boost در بین تنظیمات هست یا نه نیاز به راهنمایی داشته باشه.



بله این کار را کردم که گزارش را میدم .
اول این رو بگم که در هر دو حالت (با فعال کردن و غیرفعال کردن Turbo Boost) ، برنامه ی شما ، در حالت های مختلف (یک نخی در یک پروسه و تک نخی در دو پروسه . دو نخی در یک پروسه و دو نخی در دو پروسه) ، هیچ فرقی با گزارش هایی که قبلا دادم ، نکرد . من فکر میکردم مقدار cpu usage در برنامه ی شما ، سرعت پردازش را میده اما اگه اشتباه نکنم ، مقدار این رو میده که یک هسته چند درصدش فعال بود (درسته؟) . یعنی سرعت پردازش نخ را نمیسنجه پس فرکانس برای اون هسته ، چه بالا باشه یا پایین ، فرقی به آمارش نداره .

اجرای یک نخ به تنهایی در یک برنامه و بدون محدودیت در انتخاب هسته دقیقا مشابه همون کاری است برنامه در 10 ثانیه ابتدایی میکنه و باید 100 یا نزدیک به 100 باشه، به قول شما هم ربطی به فرکانس پردازنده نداره، چون مقایسه نسبی است، وقتی یکسان باشند باید 100 درصد باشه.
ارتباط مستقیمی هم به توان هسته نداره، یک زمانی طول میکشه که اون تک نخ اجرا بشه که اون زمان میشه معیار مقایسه.
اما برسیم به مقایسه اون معیار با اجرای دو نخ در دو برنامه مجزا. شما مدعی شدید که Turbo Boost در حالتی که یک هسته کارکرد بالا داره نسبت به حالتی که تعداد هسته بیشتری کارکرد بالا دارن فرکانس بالاتری اعمال میکنه.
و گفتید به همین خاطر در اجرای دو نخ در دو برنامه که بیشتر از یک هسته درگیر شدن کارکرد هر نخ کمتر از اون اجرای تک نخی 100% یا فرضا 98% شده.
اینکه ربطی به برنامه من نداره که فرکانس هسته چی باشه، هر چقدر فرکانس بالاتر باشه پردازش سریعتر میشه و زمان اجرای نخ کمتر میشه. برنامه زمانی درصد رو کمتر یا بیشتر نشون میده که زمان سپری شده از زمان اجرای تک نخی اول برنامه کمتر یا بیشتر باشه.
اگر این تغییر فرکانس بین اجرای تک نخی و چند نخی بوجود بیاد، در برنامه خودش رو بصورت درصد بالا و پایین نشون میده. اگر دلیل شما دخالت Turbo Boost در فرکانس هسته ها است، حالا که غیر فعال ئه، چرا همچنان همون شرایط برقرار ئه؟
من در همون پست قبلی گفتم که شما وقتی Turbo Boost رو غیر فعال کنید همین شرایط برقرار ئه و ربطی به Turbo Boost نداره. Turbo Boost نقش اش افزایش کارایی است، اگر قرار بود هر چقدر از پردازنده بیشتر کار میکشیم Turbo Boost هسته ها رو کندتر کنه که همه غیر فعالش می کردند. کی خوشش میاد پردازنده اش وقتی که نیاز به پردازش بالاتر داره کندتر بشه.

the king
پنج شنبه 07 آذر 1398, 22:12 عصر
در 1 نخ در 1 پروسه ، هم برای وقتی که Turbo Boost Clock فعال هست (نتیجه ی زمان اجرای کد ،23.519 ثانیه شد) (در این حالت ، میانگین کلاک پردازنده بین 3.33 تا 3.35 بود که حالا هی بالا و پایین تر میرفت اما میانگین اش این بود) و هم در زمانی که Turbo Boost Clock غیر فعال هست (نتیجه ی زمان اجرای کد ، 24.687 ثانیه شد) (در این حالت ، کلاک پردازنده ، 3.19 بود) را مقایسه کنید ، میبینید که اختلاف کلاک ها ، تقریبا 100 مگاهرتز ، یعنی تقریبا 1.047 برابر ، کلاک شون با هم اختلاف داشت و تفاوت زمانی شون هم 1.048 برابر هست .

بجز این ، تفاوت را بیشتر در پردازنده هایی بهتر میشه متوجه شد که اختلاف turbo boost clock و کلاک پایه شون ، زیاد و زیادتر باشه (حداقل 400 مگاهرتز یا بیشتر) . معمولا لپتاپ ها اختلاف شون خیلی زیاد تر هه .
این داده های شما است :


/// Turbo Boost: OFF
/// 1 thread 24687 ms
/// 2 threads 24649 ms, 24748 ms
/// 3 threads 25668 ms, 25593 ms 25662 ms
/// 4 threads 26048 ms, 25953 ms 26122 ms 26231 ms
///
/// 1+1 threads 24723 ms, 24695 ms
/// 2+2 threads 25907 ms, 25879 ms, 25886 ms, 26217 ms
///
/// Turbo Boost: ON
/// 1 thread 23519 ms
/// 2 threads 23635 ms, 23646 ms
/// 3 threads 24339 ms, 24291 ms 24319 ms
/// 4 threads 25278 ms, 25186 ms 25320 ms 25339 ms
///
/// 1+1 threads 24017 ms, 23953 ms
/// 2+2 threads 25610 ms, 25504 ms, 25425 ms, 25767 ms

طبق گفته شما وقتی یک هسته فعالیتش زیاد میشه Turbo Boost فرکانس هسته رو بالاتر میبره و این فرکانس با افزایش فشار روی سایر هسته ها کم میشه و دلیل کاهش سرعت اجرای چند نخ نسبت به یک نخ این Turbo Boost ئه.
حالا شما Turbo Boost رو غیر فعال کردید که نشون بدید بدون اثر این Turbo Boost اجرای چند هسته ای کاهش سرعتی که با Turbo Boost فعال داشتید ندارن.
ولی زمان اجرای تک نخی 24687 تون در 2+2 نخ رسیده به 25907 و 25879 و 25886 و 26217 میلی ثانیه. کند تر نشده؟

طبق گفته شما این Turbo Boost بود که فرکانس هسته پایین تری رو برای اجرای چند نخی اعمال میکرد و منجر به کندی اجرای چند نخی نسبت به تک نخ شده بود. که غیر فعالش کردید تا تاثیر نذاره.
اجرای تک نخی با Turbo Boost غیر فعال چقدر بود؟ 24687 میلی ثانیه، وقتی 4 نخ رو اجرا کردید به چند رسید؟ جمعا 104354 میلی ثانیه، یعنی 5.68 درصد نخ های کند تری بودن :


100 * (24687 - (104354 / 4)) / 24687 = 5.68

با اجرای 3 نخی به چند رسید؟ حمعا 76923 میلی ثانیه، یعنی هسته ها 3.86 درصد کند تر شدن.
با احرای 2 + 2 نخی به چند رسید؟ جمعا 103889 میلی ثانیه، یعنی هسته ها 5.21 درصد کند تر شدن. چیزی هم در حلقه for کدتون نداشتید که بین شون مشترک باشه.
شما که مدعی هستید این نخ ها هر کدوم میتوانند در هسته مجزایی اجرا بشن و دیگه Turbo Boost هم تداخلی در محاسبات نداره دیگه برای کاهش کارایی شون چه دلیلی دارید؟

SajjadKhati
پنج شنبه 07 آذر 1398, 22:54 عصر
حتما لینک منبع چیزی رو که گفتید پیدا کنید، لازمش دارم، این مساله مهمی که شما پیدا کردید در سایت اینتل که نبود، چیزی که اینتل عمومی اعلامش نکنه حتما ارزشمنده.
شما اگر از این بچه های سخت افزار کسی رو سراغ دارید که معلوماتشون در حد جزئیات پردازنده های مدرن اینتل باشه معرفی شون کنید ولی توقع نداشته باشید که یک دانشجو یا استاد رشته سخت افزار اینها رو بدونه.
چون در ایران فناوری سخت افزاری و سطح آموزشی در این موارد خیلی سطح پایین و منسوخ ئه و همچین افرادی کیمیا هستند.


بله شما درست میگید، لابد اینتل داره اشتباه میگه. من عین متن سوال و جواب رو از FAQ اینتل نقل قول کردم :
https://www.intel.com/content/www/us/en/support/articles/000007359/processors/intel-core-processors.html
که متن کاملش رو هم پیوست همین پست کردم.


بله. اصلا مورد عجیبی نیست. خیلی عادیه. سازنده لپ تاپ با توجه به توان تغذیه باطری و سیستم خنک کننده ای که بکار برده ممکنه ببینه نمیتونه از عهده تامین انرژی و حرارت فرکانس بالاتر پردازنده بربیاد و در نتیجه ترجیح بده غیر فعال نگهش داره.


من هم دونه به دونه گزینه های BIOS سیستم ام رو میشناسم و هم با انواع مختلف BIOS ها کار کردم.
گمان نمی کنم کسی که برای تغییر تنظیمات BIOS برنامه اسمبلی مینوشته برای اینکه تشخیص بده یک مورد ساده ای مثل Turbo Boost در بین تنظیمات هست یا نه نیاز به راهنمایی داشته باشه.


اجرای یک نخ به تنهایی در یک برنامه و بدون محدودیت در انتخاب هسته دقیقا مشابه همون کاری است برنامه در 10 ثانیه ابتدایی میکنه و باید 100 یا نزدیک به 100 باشه، به قول شما هم ربطی به فرکانس پردازنده نداره، چون مقایسه نسبی است، وقتی یکسان باشند باید 100 درصد باشه.
ارتباط مستقیمی هم به توان هسته نداره، یک زمانی طول میکشه که اون تک نخ اجرا بشه که اون زمان میشه معیار مقایسه.
اما برسیم به مقایسه اون معیار با اجرای دو نخ در دو برنامه مجزا. شما مدعی شدید که Turbo Boost در حالتی که یک هسته کارکرد بالا داره نسبت به حالتی که تعداد هسته بیشتری کارکرد بالا دارن فرکانس بالاتری اعمال میکنه.
و گفتید به همین خاطر در اجرای دو نخ در دو برنامه که بیشتر از یک هسته درگیر شدن کارکرد هر نخ کمتر از اون اجرای تک نخی 100% یا فرضا 98% شده.
اینکه ربطی به برنامه من نداره که فرکانس هسته چی باشه، هر چقدر فرکانس بالاتر باشه پردازش سریعتر میشه و زمان اجرای نخ کمتر میشه. برنامه زمانی درصد رو کمتر یا بیشتر نشون میده که زمان سپری شده از زمان اجرای تک نخی اول برنامه کمتر یا بیشتر باشه.
اگر این تغییر فرکانس بین اجرای تک نخی و چند نخی بوجود بیاد، در برنامه خودش رو بصورت درصد بالا و پایین نشون میده. اگر دلیل شما دخالت Turbo Boost در فرکانس هسته ها است، حالا که غیر فعال ئه، چرا همچنان همون شرایط برقرار ئه؟



خیلی ممنون استاد .
استاد ، برای من که همه ی اسناد و مدارک نشون میده که هر نخی که میسازیم (توسط کلاس Thread) ، درون یک هسته ی منطقی (چه میخواد اون هسته ی منطقی داخل یک هسته ی فیزیکی باشه یا نباشه) ، بصورت همزمان اجرا میشه .
سند آخر اینکه شما میگین هر تعداد نخ که میسازیم ، در یک لحظه فقط در یک هسته ی فیزیکی اجرا میشه ، پس چرا کد زیر :



private void TransparentControl4_Click(object sender, EventArgs e)
{
Thread[] thread = new Thread[16];


for (int i = 0; i < thread.Length; i++)
{
thread[i] = new Thread(new ThreadStart(this.NewThreadMethod_1));
}


for (int i = 0; i < thread.Length; i++)
{
thread[i].Start();
}



}


private void NewThreadMethod_1()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();


for (long counter = 0; counter < 10000000000; counter++)
{
}


stopwatch.Stop();
long elapsed = stopwatch.ElapsedMilliseconds;
MessageBox.Show("elspsed : " + elapsed.ToString() + " ms", "New Thread");
}




وقتی در پردازنده ی خودم (که 4 هسته ی فیزیکی داره) ، تعداد آرایه ی thread را اگه 1 یا 2 یا 3 یا 4 عضو بگیرم (یعنی 1 یا 2 یا 3 یا 4 نخ میسازم و اجرا میکنم) ، تقریبا زمان شون با هم یکی هست (با اختلاف 2 تا 3 ثانیه) و تقریبا همه شون بین 23 تا 26 ثانیه ، کدش اجرا میشه اما تعداد این آرایه را از 4 تا که بیشتر میکنم (5 و بالاتر) ، هر بار 7 ثانیه به اجراش اضافه تر میشه و دیرتر تموم میشه؟

یعنی وقتی 5 نخ (5 عضو برای اون آرایه ی thread) میسازم ، 32 ثانیه طول میکشه ، 6 نخ ، 40 ثانیه طول میکشه ، 7 نخ ، 45 ثانیه طول میکشه ، 8 نخ ، 51 ثانیه طول میکشه ، 10 نخ ، 63 ثانیه طول میکشه ، 12 نخ ، 75 ثانیه طول میکشه و 16 نخ ، 100 ثانیه طول میکشه؟

چرا تا تعداد نخ هام ، هنوز برابر با تعداد هسته هام نشد ، اجرای همه شون تقریبا 25 ثانیه زمان میبرد ولی تعداد نخ هام که بیشتر از تعداد هسته هام شد ، به همون اندازه ، اجراشون بیشتر طول کشید؟
چرا زمانی که 8 نخ ساختم ، تقریبا 2 برابر بیشتر از زمانی که 1 نخ یا 2 نخ یا 3 نخ یا 4 نخ ساختم ، طول کشید؟
چرا زمانی که 16 نخ ساختم ، تقریبا 4 برابر بیشتر از زمانی که 1 نخ یا 2 نخ یا 3 نخ یا 4 نخ ساختم ، طول کشید؟

قطعا شما هم اگه توی پردازنده تون از 8 نخ بیشتر بسازین ، به همون مقدار ، به زمان اش اضافه میشه اما زیر 8 نخ (مخصوصا 4 نخ چون 4 هسته ی فیزیکی دارین) ، زمان شون فرق خاصی نخواهند داشت .





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

همون عکسی که دادین ، 3 سئوال مونده به آخری را دقت کنین :


how can i see the highest turbo boost frequency for my processor?
if you set the number of cores to one in the BIOS and run the intel proccessor identification utility , it shows the highest turbo boost frequency .

اگه اشتباه نکنم ترجمه اش اینه :
"اگر تعداد هسته را به (مقدار) 1 در بایوس تنظیم کنید ، و برنامه ی intel proccessor identification را اجرا کنید ، بیشترین فرکانس turbo boost را نمایش میده ."

اگه ترجمه را تایید میکنید پس بگید چرا گفته وقتی میتونید متوجه ی بیشترین فرکانس turbo boost بشید که تعداد هسته را در بایوس تون به 1 تنظیم کنید (و موقتا بقیه ی هسته ها را نادیده بگیرید) ؟

the king
جمعه 08 آذر 1398, 01:38 صبح
خیلی ممنون استاد .
استاد ، برای من که همه ی اسناد و مدارک نشون میده که هر نخی که میسازیم (توسط کلاس Thread) ، درون یک هسته ی منطقی (چه میخواد اون هسته ی منطقی داخل یک هسته ی فیزیکی باشه یا نباشه) ، بصورت همزمان اجرا میشه .
سند آخر اینکه شما میگین هر تعداد نخ که میسازیم ، در یک لحظه فقط در یک هسته ی فیزیکی اجرا میشه ، پس چرا کد زیر :



private void TransparentControl4_Click(object sender, EventArgs e)
{
Thread[] thread = new Thread[16];


for (int i = 0; i < thread.Length; i++)
{
thread[i] = new Thread(new ThreadStart(this.NewThreadMethod_1));
}


for (int i = 0; i < thread.Length; i++)
{
thread[i].Start();
}



}


private void NewThreadMethod_1()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();


for (long counter = 0; counter < 10000000000; counter++)
{
}


stopwatch.Stop();
long elapsed = stopwatch.ElapsedMilliseconds;
MessageBox.Show("elspsed : " + elapsed.ToString() + " ms", "New Thread");
}




اولا واحد بزرگی بکار نبرید، میلی ثانیه در مقایسه با فرکانس پردازنده واحد بزرگیه، از تیک استفاده کنید که ارزیابی دقت کافی داشته باشه.
ثانیا شما که اصلا کاری با سند و مدرک ندارید، مستندات خود Intel رو که قبول ندارید هیچ نتیجه محاسبات خودتون رو هم جوری که نیست تفسیر می کنید.
سوالی که نوشتم رو که خوندید؟ ازتون پرسیدم "شما که مدعی هستید این نخ ها هر کدوم میتوانند در هسته مجزایی اجرا بشن و دیگه Turbo Boost هم تداخلی در محاسبات نداره دیگه برای کاهش کارایی شون چه دلیلی دارید؟"
چه جوابی برای سوالم دارید؟



وقتی در پردازنده ی خودم (که 4 هسته ی فیزیکی داره) ، تعداد آرایه ی thread را اگه 1 یا 2 یا 3 یا 4 عضو بگیرم (یعنی 1 یا 2 یا 3 یا 4 نخ میسازم و اجرا میکنم) ، تقریبا زمان شون با هم یکی هست (با اختلاف 2 تا 3 ثانیه) و تقریبا همه شون بین 23 تا 26 ثانیه ، کدش اجرا میشه اما تعداد این آرایه را از 4 تا که بیشتر میکنم (5 و بالاتر) ، هر بار 7 ثانیه به اجراش اضافه تر میشه و دیرتر تموم میشه؟

تقریبا زمان شون یکی هست؟ مگه نمی گید تقریبا برابر هستند با اختلاف 2 الی 3 ثانیه، چرا پس نمی گید وقتی تعداد نخ ها رو بیشتر می کنم تقریبا برابر هستند با اختلاف 7 ثانیه؟ چه معیاری گذاشتید برای اینکه 2 الی 3 ثانیه اختلاف ناچیزی است و 7 ثانیه هست؟
اسناد شما میگه وقتی شما تعداد نخ بیشتری ساختید که بنا به گفته خودتون هر کدوم در هسته فیزیکی مستقل اجرا شدن کارکرد اومد پایینتر. مستقل اجرا شدن و اجراشون کندتر شد؟ اون اختلاف 2 الی 3 ثانیه رو ضرب کنید در فرکانس پردازنده تون ببینید چند سیکل میشه؟
اون 10000000000 بار تکرار حلقه تون رو 5.68 درصدش رو حساب کنید ببینید چند بار تکرار حلقه تون میشه. مقداری نیست؟ شما که میگید پردازنده تون داره هر نخ رو در هسته مجزا اجرا میکنه چطور اینقدر سیکل ساعت و اونقدر تعداد بار تکرار حلقه تون رو از دست دادید؟



یعنی وقتی 5 نخ (5 عضو برای اون آرایه ی thread) میسازم ، 32 ثانیه طول میکشه ، 6 نخ ، 40 ثانیه طول میکشه ، 7 نخ ، 45 ثانیه طول میکشه ، 8 نخ ، 51 ثانیه طول میکشه ، 10 نخ ، 63 ثانیه طول میکشه ، 12 نخ ، 75 ثانیه طول میکشه و 16 نخ ، 100 ثانیه طول میکشه؟

خوب که این خیلی طبیعیه، وقتی تعداد نخ ها زیاد میشه، هسته دائم در حال سوئیچ شدن بین نخ ها میشه و سربار اجرای سوئیچ هم فشار روی اون هسته ایجاد میکنه و هم سایر هسته ها و هم فعالیت بیشتر نخ های مدیریتی سیستم و در نتیجه کارایی بخاطر تعدد و ترافیک درخواست ها میاد پایین. وقی از یک در یک صف آدم به نوبت رد میشن نرخ عبور (آدم بر ثانیه) از در بیشتره یا وقتی 16 نفر آدم حمله میکنن سمت در و ترافیک ایجاد میشه؟
اتفاقا این سوال رو شما باید توضیح بدید، مگه شما نمی گید که نخ های من روی چهار هسته فیزیکی همزمان اجرا میشن؟
مرحله 1 - سه یا چهار نخ هر کدوم روی یک هسته شروع به اجرا می کنند. حالا بین شون سوئیچ هم ممکنه بشه، مهم نیست.
مرحله دوم - چند نخ در اجرای مرحله اول کارشون تموم شده و سیستم عامل پرونده اون سه یا چهار نخ رو میبنده میذاره کنار و هسته ها می توانند نخ های دیگری از برنامه تون رو که در صف باقی موندن اجرا کنند.
با فرض شما وقتی به مرحله دوم میرسیم همه اون هسته ها با اختلاف زمانی کم کارشون با یک نخ برنامه تموم شده.
حالا چطوری بین 5 نخی و 6 نخی اختلاف زمانی زیاد دارید؟ چه فرقی می کنه 5 نخی و 6 نخی؟ مرحله دوم شون رو تصور کنید. در هر دو وضعیت 5 نخی و 6 نخی وقتی به مرحله دوم رسیدیم به تعداد نیاز نخ های باقی مونده هسته بیکار هست.
مستندات شما میگه بین اجرای 5 نخی و 6 نخی پردازنده 8 ثانیه سکته کرده که اینقدر اختلاف زمانی دارن؟



چرا تا تعداد نخ هام ، هنوز برابر با تعداد هسته هام نشد ، اجرای همه شون تقریبا 25 ثانیه زمان میبرد ولی تعداد نخ هام که بیشتر از تعداد هسته هام شد ، به همون اندازه ، اجراشون بیشتر طول کشید؟

با توصیفی که شما از اجرای نخ هاتون دارید، هیچ توضیحی نمیشه داد، شما با فرض اشتباه یک سوالی طرح می کنید که چون فرض مساله غلطه نه من و نه خودتون نمی تونید با فرمول ریاضی توضیحش بدید.
وقتی فرض رو بر این گرفتید که هر نخ میتونه مستقل روی هسته ای مجزا همزمان با نخ دیگری از برنامه تون اجرا بشه، باید به این نتیجه برسید که در پردازنده 4 هسته ای که بار کاری عادی اش در حد 25 درصد نیست و کمتره،
سه هسته همواره اونقدر آزاد و بیکار هستند که بتوانند سه نخ برنامه شما رو در زمان n ثانیه تموم کنند و بعد سه نخ دیگه رو و عملا در بدترین شرایط زمان اجرای کامل 6 نخ تون با 5 نخ تون باید برابر باشه و نباید بیشتر طول بکشه.
چون وقتی سه هسته سرش خلوت ئه، اجرا کردن یک نخ و دو نخ و سه نخ باقی مونده زمان متفاوتی میخواد؟ مستنداتون این مساله رو تایید می کنه؟ نمیکنه.



چرا زمانی که 8 نخ ساختم ، تقریبا 2 برابر بیشتر از زمانی که 1 نخ یا 2 نخ یا 3 نخ یا 4 نخ ساختم ، طول کشید؟
چرا زمانی که 16 نخ ساختم ، تقریبا 4 برابر بیشتر از زمانی که 1 نخ یا 2 نخ یا 3 نخ یا 4 نخ ساختم ، طول کشید؟

قطعا شما هم اگه توی پردازنده تون از 8 نخ بیشتر بسازین ، به همون مقدار ، به زمان اش اضافه میشه اما زیر 8 نخ (مخصوصا 4 نخ چون 4 هسته ی فیزیکی دارین) ، زمان شون فرق خاصی نخواهند داشت .

وقتی 4 نخ میساختید پردازنده تون با حداکثر توان پاسخگویی اش درگیر شده، دائم در حال سوئیچ کردن بین نخ های برنامه و سایر برنامه ها است، اون نخ های دیگه کارشون کم ئه و زود تموم میشه ولی نخ های شما که ول کن نیستن و حالا حالا ها پردازش میخوان.
وقتی نخ جدیدی به صف درخواست ها اضافه میکنید مجالی هست برای پاسخگویی؟ نیست. صف درخواست پردازنده از سیستم عامل به حد اشباع رسیده، پردازنده گلوگاه شده. سیستم عامل دستش بسته است. حالا هی شما نخ جدید اضافه کنید، پردازنده که نمیتونه کاری برای افزایش سرعت بکنه. نخ گرامی تون باید صبر کنه تا نوبت اش برسه، به عبارتی دیگه نخ دیگری از برنامه تون کارش تموم بشه. اون نخ ها رو می بینید در Task Manager که سایر برنامه دارن؟ همه شون همواره در حال اجرا نیستن ولی به کررات درخواست در کم دارن.
الات مظلوم و کم صدا کار میکنن چون فرصت پردازش دارن. اما وقتی ترافیک برای پردازنده ایجاد بشه همون نخ هایی که کارشون کم ئه میشن سربار سیستم و در بین اجرای نخ های شما دائم نوبت اجرا میگیرن. اینطوریه که سوئیچ شدن سربار زیادی ایجاد میکنه.



همون عکسی که دادین ، 3 سئوال مونده به آخری را دقت کنین :


how can i see the highest turbo boost frequency for my processor?
if you set the number of cores to one in the BIOS and run the intel proccessor identification utility , it shows the highest turbo boost frequency .

اگه اشتباه نکنم ترجمه اش اینه :
"اگر تعداد هسته را به (مقدار) 1 در بایوس تنظیم کنید ، و برنامه ی intel proccessor identification را اجرا کنید ، بیشترین فرکانس turbo boost را نمایش میده ."

اگه ترجمه را تایید میکنید پس بگید چرا گفته وقتی میتونید متوجه ی بیشترین فرکانس turbo boost بشید که تعداد هسته را در بایوس تون به 1 تنظیم کنید (و موقتا بقیه ی هسته ها را نادیده بگیرید) ؟
چون طبق مستندات Intel Turbo Boost سقف فرکانسی که به پردازنده اختصاص داده میشه و طبعا متغیر ئه به اینها وابستگی داره، در همون صفحه ای نوشته شده که ازش نقل قول کرده بودم :


Type of workload
Number of active cores
Estimated current consumption
Estimated power consumption
Processor temperature

اینطوری که پردازنده بر اساس اینکه چند هسته فعال و غیر فعال هست، حرارت پردازنده چقدر ئه، چقدر برق مصرف میکنه و چقدر جریان میکشه و چقدر درخواست پردازش روی پردازنده هست فرکانس رو تغییر میده.
وقتی فقط یک هسته رو فعال کنید، هسته های دیگه از مدار خارج میشن و مصرف انرژی پردازنده به میزان متناسب کم میشه، جریانی که پردازنده میکشه به میزان متناسب کم میشه، حرارت پردازنده هم که موثر از اینها است کم میشه.
در نتیجه همه اون موارد که سقفی پایین تر از حداکثر میزان فرکانس ایجاد میکردن از بین میرن، خود بار کاری الان تعیین کننده فرکانس میشه که اونم یک پارامتر جدا است، سقف نیست.
شما در Intel proccessor identification utility میخواهید سقف فرکانس پردازنده رو بخونید، نه فرکانس متغیری که در این لحظه توسط Turbo Boostبرای CPU تعیین شده.
اگر همه هسته ها فعال باشند، احتمال داره با توجه به مشخصات پردازنده یا مادربورد و سیستم خنک کننده سقف های مضاعف تحمیل بشن و سقف فرکانسی که Intel proccessor identification utility اعلام میکنه کمتر از چیزی باشه که در بهترین شرایط سخت افزاری و به عنوان حداکثر فرکانس Turbo Boost برای پردازنده بدست میاد. دقت کنید که صحبت از حداکثر فرکانس پردازنده با Turbo Boost ئه، نه حداکثر فرکانس وقتی همه هسته ها رو فعال کردید و بصورت عادی از سیستم استفاده می کنید.
ممکنه بخاطر محدودیت های سخت افزاری سایر پارامتر ها هیچوفت نتوانید در عمل از اون سقف فرکانس استفاده کنید، مگر در همون حالتی که سیستم تک هسته ای یا حتی دو هسته ای شده.
میتوانید امتحان کنید، ممکنه با هر چهار هسته فعال هم به اون حداکثر فرکانس در عمل برسید، اما تا وقتی که پردازنده زیادی داغ نشده.

SajjadKhati
جمعه 08 آذر 1398, 20:10 عصر
اولا واحد بزرگی بکار نبرید، میلی ثانیه در مقایسه با فرکانس پردازنده واحد بزرگیه، از تیک استفاده کنید که ارزیابی دقت کافی داشته باشه.
ثانیا شما که اصلا کاری با سند و مدرک ندارید، مستندات خود Intel رو که قبول ندارید هیچ نتیجه محاسبات خودتون رو هم جوری که نیست تفسیر می کنید.
سوالی که نوشتم رو که خوندید؟ ازتون پرسیدم "شما که مدعی هستید این نخ ها هر کدوم میتوانند در هسته مجزایی اجرا بشن و دیگه Turbo Boost هم تداخلی در محاسبات نداره دیگه برای کاهش کارایی شون چه دلیلی دارید؟"
چه جوابی برای سوالم دارید؟


سلامی مجدد استاد .
خیلی ممنون از جواب تون .
ببینید ، اول اینکه نمیدونم چرا زمانی که کد رو اجرا میکنم ، گاها (نه همیشه) وقتی ساعت ویندوز را کلیک میکنم (تا گذر ثانیه ها را ببینم) با زمانی که کد اجرا میشه و ساعت ویندوز را نمایش نمیدم (ویندوز 10) ، در زمان اجرای کد ، تفاوت ایجاد میشه مخصوصا اینکه زمانی که تعداد نخ هایی که میسازم ، از تعداد هسته هام بیشتر بشه . مثلا وقتی 8 نخ میسازم ، اختلاف این حالت ها (اختلاف زمان اجرای کد در این دو حالت مختلف) حتی به 7 ثانیه هم میرسه که هر بار متغییر هه .
این قضیه را تازه متوجه شدم . دلیل شو نمیدونم . ضمنا در زمانی که تعداد نخ ها بیشتر از تعداد هسته هام میشه ، ممکنه Stopwatch هم حتی تا چند ثانیه اشتباه عمل کنه (البته شاید اشتباه نباشه بخاطر عملکرد نخ ها که هر لحظه متوقف میشن و ممکنه حتی چند ثانیه هم یه نخ اجرا نشه و معلوم هم نیست که زمان شروع اجراشون با هم برابر (از لحاظ واحد بزرگ ثانیه منظورمه) باشن) .
این قضیه ، هر چند خیلی کمتر ولی ممکنه زمانی که تعداد نخ هام هم برابر یا کمتر از تعداد هسته هام باشه هم اتفاق بیافته .

ضمنا ، مشخص هست که وقتی 3 یا مخصوصا 4 هسته از پردازنده ام بصورت همزمان درگیر میشن ، کارایی باید کمتر بشه چون بقیه ی پروسه هام (task manager و بقیه) هم که گفتم در حالت استاندارد ، 5 تا 10 درصد از توان پردازنده را میگیرن . اینها هم نیاز به پردازش دارن . علاوه بر این ها (وقتی هسته های بیشتری درگیر میشن) ، طبعا احتمال سوئیچ ها هم بیشتر میشه (چه توی نخ های پروسه ی خودم چه سوئیچ به نخ های بقیه ی پروسه ها) و بنابراین سربار بیشتر و کاهش کارایی اتفاق میافته .





تقریبا زمان شون یکی هست؟ مگه نمی گید تقریبا برابر هستند با اختلاف 2 الی 3 ثانیه، چرا پس نمی گید وقتی تعداد نخ ها رو بیشتر می کنم تقریبا برابر هستند با اختلاف 7 ثانیه؟ چه معیاری گذاشتید برای اینکه 2 الی 3 ثانیه اختلاف ناچیزی است و 7 ثانیه هست؟


استاد ، چرا منظورم را یه جور دیگه ای متوجه میشین؟!
الان شما نمیگید همه ی نخ ها در پروسه ام ، بصورت همزمان ، فقط در یک هسته ی فیزیکی اجرا میشن؟
اگه اینطور بود ، (در کد پست قبلی که دادم) ، وقتی در پروسه ام ، یک نخ را اجرا که کردم و زمان اجراش 25 ثانیه (میانگین) بود ، نخ دوم را که اجرا میکردم ، زمان اجراش باید میانگین 7 ثانیه بهش اضافه میشد و 32 ثانیه میشد . نخ سوم هم باید زمان اجراش 39 ثانیه و زمان اجرای نخ چهارم 46 ثانیه میشد .
زمان اجرای نخ پنجم هم 53 ثانیه و نخ ششم هم 60 ثانیه میشد .
اینها بصورت میانگین بودن (حالا دو یا 3 ثانیه کمتر یا بیشتر) .
تا اینجا را متوجه شدین؟

پس چرا وقتی که 4 نخِ اول را میسازم ، یعنی 1 نخ یا 2 نخ یا 3 نخ یا 4 نخ را میسازم و اجرا میکنم ، در پردازنده ی من ، زمان اجراشون تقریبا با هم برابر هست ؟ (دوباره روی اختلاف دو سه ثانیه اش تاکید نکنین . اولا این اختلاف را در قسمت اول در همین پست جواب دادم و دوما بصورت مفهومی ، منظورم رو همین الان در پاراگراف بالا گفتم)
اما همین که تعداد نخ هام از تعداد هسته هام بیشتر میشه ، شاهد این هستم که به ازای هر نخ ، تقریبا 7 ثانیه زمان اجراش هم بیشتر طول میکشه؟

شما خودتون هم این قضیه را در پردازنده تون تست کنین ، متوجه میشین .




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


کندتر شد؟!!
کجاش کندتر شد؟
تعداد دستورات اجرایی اش چهار برابر شد ، یعنی در چهار نخ اجرا شد (به ازای هر نخ ، 10000000000 (ده میلیارد دستور) اجرا میشه و بنابراین در چهار نخ ، چهل میلیارد دستور اجرا میشه) اما زمان اجراش 3 ثانیه کمتر شد (26 ثانیه شد) . اگه قرار بود همه ی این چهار نخ در یک هسته ی فیزیکی اجرا بشه ، حداقل باید زمان اجراش بیشتر از 2 برابر میشد . یعنی بیشتر از 50 ثانیه میشد (قطعا باز هم باید بیشتر از این مقدار میشد و به احتمال زیاد ، نزدیک به 4 برابر میشد)
این کاهش کارایی دو تا سه ثانیه را هم در اولِ این پست ، گفتم .




اون اختلاف 2 الی 3 ثانیه رو ضرب کنید در فرکانس پردازنده تون ببینید چند سیکل میشه؟


من نمیدونم این قدر فوکوسی که روی این اختلاف دو تا سه ثانیه کردین ، چرا روی اختلافی به اون عظمت نمیکنین؟
چرا نمیگین چرا در این پردازنده ، اجرای 1 نخ تا 4 نخ ، تفاوت خاصی نداره اما چرا از اون به بعد ، اختلاف همینطور افزایش پیدا میکنه؟




اون 10000000000 بار تکرار حلقه تون رو 5.68 درصدش رو حساب کنید ببینید چند بار تکرار حلقه تون میشه. مقداری نیست؟ شما که میگید پردازنده تون داره هر نخ رو در هسته مجزا اجرا میکنه چطور اینقدر سیکل ساعت و اونقدر تعداد بار تکرار حلقه تون رو از دست دادید؟


در قسمت بالایی همین پست گفتم .




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


طبیعیه؟!
زیاد شدن نخ را چجوری در نظر میگیرید؟ چطور نخ یه دونه باشه ، زیاد نیست ، دو تا باشه ، باز هم زیاد نیست ، سه تا باشه ، باز هم زیاد نیست ، چهار تا باشه ، باز هم زیاد نیست اما یهو به پنجمین نخ (یا نخ های بیشتر) که میرسه ، زیاد حساب میشه؟!

توی تک نخ که مشکلی نداریم . درسته؟ پس تا اینجا قبوله که فرضا زمان اجرای یک نخ ، حدود 24 ثانیه (در یک هسته) طول میکشه . حالا این قضیه ی همجوم 16 نفر به یکباره برای خروج از یک در را که مظرح کردین ، این ، چه زمانی به نظرتون پیش میاد؟
الان به نظر شما ، وقتی بیشتر از یک نخ بسازیم برای اجرا (هر چه تعداد نخ ها بیشتر باشه) ، پس قضیه ی هجوم و ترافیک پیش میاد که هر چی این نخ بیشتر باشه ، یعنی هجوم بیشتر و ترافیک بیشتر و سرعت پردازش هم به همون نسبت ، کمتر میشه . تا اینجا قبول؟ (همچین چیزی مد نظرتونه دیگه . درسته؟)
پس وقتی تعداد نخ ها از یکی بیشتر بشه ، دو برابر هجوم اتفاق میافته و باید سرعت کمتر بشه (حالا نمیگم دو برابر باید سرعت کمتر بشه) . یعنی کلا ، کم شدن سرعت ، با افزایش نخ را که قبول دارین (این طور که استدلال میکنید) (قبوله؟)

پس چرا یک نخ ، تبدیل به دو نخ میشه ، سرعت پردازش اش در پردازنده ی من ، کمتر نمیشه و همونه؟ چرا به 3 نخ که میرسه ، باز هم همونه تقریبا؟ چرا به چهار نخ میرسه ، باز هم تقریبا همون مقدار از زمان طول میکشه تا اجرا بشه؟ اگه در پردازنده ای که 8 هسته ی فیزیکی که داره هم اجرا کنید ، باز هم سرعت پردازش یک نخ با 8 نخ ، تفاوت خواصی نمیکنه (مثل پردازنده ی من که سرعت اجرای 1 نخ تا 4 نخ ، فرق خاصی نداره) . اگه توی پردازنده ای که 32 هسته ی فیزیکی داره تست کنید ، اجرای 1 نخ با 32 نخ ، تفاوت زمانی خاصی نخواهند داشت .

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

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

این هم قبول دارین که اختلاف قدرت در هر یک هسته (تک هسته) توی هر پردازنده ای ، بخاطر تعداد هسته های منطقی در اون هسته ی فیزیکی و بعد هم بخاطر فرکانس و کش و دستورالعمل های اون هسته هست . اگه دو پردازنده ای که هر دوشون ، فقط یک هسته ی منطقی بر هر هسته ی فیزیکی داشته باشن و فرکانس شون هم نردیک به هم باشه و از یک نسل از پردازنده باشن ، عملکرد تک هسته ای شون با هم تقریبا برابر هه . درسته؟
یا در واقع بذارید اینجوری بگم که وقتی بنچمارک ها نشون دادند که تقریبا عملکرد تک هسته ای دو پردازنده با هم برابر هست (یعنی حرف من و حتی استدلال بالا ام هم نیست . حرف قطعی و نتایج بنچمارک هست) ، پس طبق گفته ی شما (که نخ ها در یک هسته ی منطقی بصورت همزمان اجرا میشن) ، باید مثل پردازنده ی من ، درون این پردازنده هم وقتی 1 نخ تا 4 نخ را اجرا میکنیم ، زمان اجراش باید با زمان اجرای پردازنده ی من ، تقریبا یکسان باشه . تا اینجا را قبول دارید؟

اگه قبول نداشته باشید ، پس قطعا میگید عملکرد تک هسته ای برای این دو پردازنده ، تقریبا یکسان نیست . که هم میشه با تست دو نرم افزاری که از یک هسته استفاده میکنن متوجه شد و مخصوصا اینکه بنچمارک شون منتشر شده که نمیشه نادیده اش گرفت . پس چاره ای جز قبولش نیست :لبخند: اون پردازنده هم پردازنده ای نیست جز Pentium G3220 (واسه ی فامیل مون) که توش تست کردم و نتیجه اش را در زیر میذارم .

قبل از اعلام نتیجه ، این رو بگم که این پردازنده ی G3220 ، نسل چهارم اینتل هست و دو هسته ی فیزیکی که هر هسته اش فقط یک هسته ی منطقی داره و با فرکانس 3.00GHZ و همچنین بدون قابلیت turbo boost clock و با 3 مگ کش سطح l3 هست (به همراه ویندوز 10 نسخه ی 64 بیتی) . بنچمارک (همه ی هسته های) این پردازنده در سایت videobenchmark.net ، حدودا 3100 باید باشه (الان مقدار دقیق اش را یادم نمیاد . اینترنت بین الملل ندارم که جستجو کنم) و بنچمارک تک هسته ایش هم 1500 باید باشه . بنچمارک (همه ی هسته های) پردازنده ی من (i5 4460) هم در اون سایت ، 6600 هست و بنچمارک تک هسته ایش ، 1700 حدودا باید باشه . شما که فعلا اینترنت بین الملل دارین و میتونین توی اون سایت برین و بنچمارک دقیق شو پیدا کنین .





با برنامه ای که نوشتم و لینکش اینه (همون الگوریتم ساده ی حلقه ی for در کد بالا) :

http://s6.picofile.com/file/8380053026/MultiThread_16.rar.html

نتایج زیر در این پردازنده ی G3220 بدست اومد :



1 Th = 27 s
2 Th = 28 s
3 Th = 42 s
4 Th = 57 s
5 Th = 71 s
6 Th = 84 s
7 Th = 98 s
8 Th = 112 s


10 Th = 140 s
12 Th = 168 s
16 Th = 223 s
24 Th = 335 s


و دوباره و با دقت بیشتری در سیستم خودم هم تست را انجام دادم و نتیجه اش این شد (یه کم با تست قبلی ، فرق داره) (پردازنده ام هم که میدونین i5 4460 هه که جزئیات شو قبلا گفتم . البته با 6 مگ کش سطح l3) :



1 Th = 24 s
2 Th = 24 s
3 Th = 25 s
4 Th = 26 s
5 Th = 34 s
6 Th = 40 s
7 Th = 49 s
8 Th = 54 s




10 Th = 66 s
12 Th = 78 s
16 Th = 105 s
24 Th = 158 s


Th مخفف Thread هه و s هم ثانیه هست .
همونطور که میبینید ، نتایج اجرای دو نخِ اول در دو پردازنده ، تقریبا یکسان هست (و مطابق با بنچمارک تک هسته ای شون هست)

اگه میگید هر نخ توی یه هسته (چه منطقی یا فیزیکی) اجرا نمیشه ، چرا زمان اجرای نخ سوم شون ، این قدر اختلاف دارن؟
4460 به مدت 25 ثانیه طول کشید و G3220 به مدت 42 ثانیه؟
همینطور چرا زمان اجرای نخ چهارم شون ، باز هم متفاوت هه؟
4460 به مدت 26 ثانیه طول کشید و G3220 به مدت 57 ثانیه؟

جواب تون دو حالت بیشتر نخواهد داشت .
یا باید بگین مثلا زمان بیکاری در هسته ی G3220 ، کمتر هه و در کل ، عملکرد تک هسته ای شون ، اختلاف بسیار زیادی با هم دارند که در این صورت ، تست بنچمارک را نامعتبر کردین و هم جوابی برای دو نخِ اول ندارین .
یا باید بپذیرین که هر نخ ، در یک هسته ی منطقی (چه در یک هسته ی فیزیکی باشن یا نه) اجرا میشه .

همینطور ، دقیقا طبق بنچمارکی که برای همه ی هسته ها از دو پردازنده داده بود ، عملکرد این دو پردازنده در این کدم ، همون نسبت اختلاف را رعایت کردن . یعنی بنچمارک G3220 (برای همه ی هسته هاش) تقریبا 3100 و بنچمارک i5 4460 (برای همه ی هسته هاش) تقریبا 6600 هست . یعنی i5 4460 تقریبا 2.1 (تا 2.2) برابر سریعتر از G3220 هست که زمان اجرای نخ ها را که در بالا دادم را اگه با هم مقایسه کنید ، همین نسبت رعایت شده .

شما و هر کس دیگه ای هم میتونه این کد (و این برنامه) را تست کنه و نتیجه را اینجا بذاره و بهتون قول میدم هر چقدر پردازنده اش قویتر باشه (تعداد هسته های منطقی و فیزیکی و فرکانس و کش و ... ی بیشتری داشته باشه) ، به همون نسبت نتایج بهتری هم کسب میکنه .





اتفاقا این سوال رو شما باید توضیح بدید، مگه شما نمی گید که نخ های من روی چهار هسته فیزیکی همزمان اجرا میشن؟
مرحله 1 - سه یا چهار نخ هر کدوم روی یک هسته شروع به اجرا می کنند. حالا بین شون سوئیچ هم ممکنه بشه، مهم نیست.
مرحله دوم - چند نخ در اجرای مرحله اول کارشون تموم شده و سیستم عامل پرونده اون سه یا چهار نخ رو میبنده میذاره کنار و هسته ها می توانند نخ های دیگری از برنامه تون رو که در صف باقی موندن اجرا کنند.
با فرض شما وقتی به مرحله دوم میرسیم همه اون هسته ها با اختلاف زمانی کم کارشون با یک نخ برنامه تموم شده.
حالا چطوری بین 5 نخی و 6 نخی اختلاف زمانی زیاد دارید؟ چه فرقی می کنه 5 نخی و 6 نخی؟ مرحله دوم شون رو تصور کنید. در هر دو وضعیت 5 نخی و 6 نخی وقتی به مرحله دوم رسیدیم به تعداد نیاز نخ های باقی مونده هسته بیکار هست.
مستندات شما میگه بین اجرای 5 نخی و 6 نخی پردازنده 8 ثانیه سکته کرده که اینقدر اختلاف زمانی دارن؟


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

همینطور اگه 5 یا 6 نخ یا نخ های بیشتری را برای اجرا بسپاریم ، همین روند را داره . یعنی هر هسته ، در هر لحظه ، بخشی از اون 5 نخ یا 6 نخ (یا هر تعداد نخ) را پردازش میکنه (البته نخ های پروسسه های دیگه هم هستن) .




وقتی 4 نخ میساختید پردازنده تون با حداکثر توان پاسخگویی اش درگیر شده، دائم در حال سوئیچ کردن بین نخ های برنامه و سایر برنامه ها است،اون نخ های دیگه کارشون کم ئه و زود تموم میشه ولی نخ های شما که ول کن نیستن و حالا حالا ها پردازش میخوان.


منظورتون از پردازنده ، یک هسته ی فیزیکی از پردازنده هست یا کل هسته هاش مد نظرتونه؟
احتمالا باید یک هسته منظورتون باشه (اگه نباشه که همون حرف من میشه) . اگه منظورتون یک هسته هست ، از کجا میگید که وقتی در پردازنده ی من ، وقتی 4 نخ میسازم ، اون هسته ام داره با تمام توانش کار میکنه؟ چرا مثلا نمیگید وقتی 3 نخ میسازم ، اون هسته ام با حداکثر توانش داره کار میکنه؟ یا چرا نمیگید وقتی 16 نخ میسازم ، اون هسته ام داره با تمام توانش کار میکنه؟
ادامه ی این سئوال را در بالا پرسیده بودم .




وقتی نخ جدیدی به صف درخواست ها اضافه میکنید مجالی هست برای پاسخگویی؟ نیست. صف درخواست پردازنده از سیستم عامل به حد اشباع رسیده، پردازنده گلوگاه شده. سیستم عامل دستش بسته است. حالا هی شما نخ جدید اضافه کنید، پردازنده که نمیتونه کاری برای افزایش سرعت بکنه. نخ گرامی تون باید صبر کنه تا نوبت اش برسه، به عبارتی دیگه نخ دیگری از برنامه تون کارش تموم بشه. اون نخ ها رو می بینید در Task Manager که سایر برنامه دارن؟ همه شون همواره در حال اجرا نیستن ولی به کررات درخواست در کم دارن.
الات مظلوم و کم صدا کار میکنن چون فرصت پردازش دارن. اما وقتی ترافیک برای پردازنده ایجاد بشه همون نخ هایی که کارشون کم ئه میشن سربار سیستم و در بین اجرای نخ های شما دائم نوبت اجرا میگیرن. اینطوریه که سوئیچ شدن سربار زیادی ایجاد میکنه.


نخ جدیدم باید صبر کنه تا نخ قبلی ام کارش تموم بشه؟!
خودتون قبلا گفتین یه هسته ی منطقی ، یه تیکه از نخ را اجرا میکنه و بعد متوقف میکنه ، سراغ نخ بعدی میره و این کار را همینطور ادامه میده که همین هم درسته دیگه .
یا اینکه منظورتون چیز دیگه ای هست که متوجه نشدم .




چون طبق مستندات Intel Turbo Boost سقف فرکانسی که به پردازنده اختصاص داده میشه و طبعا متغیر ئه به اینها وابستگی داره، در همون صفحه ای نوشته شده که ازش نقل قول کرده بودم :

اینطوری که پردازنده بر اساس اینکه چند هسته فعال و غیر فعال هست، حرارت پردازنده چقدر ئه، چقدر برق مصرف میکنه و چقدر جریان میکشه و چقدر درخواست پردازش روی پردازنده هست فرکانس رو تغییر میده.
وقتی فقط یک هسته رو فعال کنید، هسته های دیگه از مدار خارج میشن و مصرف انرژی پردازنده به میزان متناسب کم میشه، جریانی که پردازنده میکشه به میزان متناسب کم میشه، حرارت پردازنده هم که موثر از اینها است کم میشه.
در نتیجه همه اون موارد که سقفی پایین تر از حداکثر میزان فرکانس ایجاد میکردن از بین میرن، خود بار کاری الان تعیین کننده فرکانس میشه که اونم یک پارامتر جدا است، سقف نیست.
شما در Intel proccessor identification utility میخواهید سقف فرکانس پردازنده رو بخونید، نه فرکانس متغیری که در این لحظه توسط Turbo Boostبرای CPU تعیین شده.
اگر همه هسته ها فعال باشند، احتمال داره با توجه به مشخصات پردازنده یا مادربورد و سیستم خنک کننده سقف های مضاعف تحمیل بشن و سقف فرکانسی که Intel proccessor identification utility اعلام میکنه کمتر از چیزی باشه که در بهترین شرایط سخت افزاری و به عنوان حداکثر فرکانس Turbo Boost برای پردازنده بدست میاد. دقت کنید که صحبت از حداکثر فرکانس پردازنده با Turbo Boost ئه، نه حداکثر فرکانس وقتی همه هسته ها رو فعال کردید و بصورت عادی از سیستم استفاده می کنید.
ممکنه بخاطر محدودیت های سخت افزاری سایر پارامتر ها هیچوفت نتوانید در عمل از اون سقف فرکانس استفاده کنید، مگر در همون حالتی که سیستم تک هسته ای یا حتی دو هسته ای شده.
میتوانید امتحان کنید، ممکنه با هر چهار هسته فعال هم به اون حداکثر فرکانس در عمل برسید، اما تا وقتی که پردازنده زیادی داغ نشده.


اگه اشتباه نکنم ، به عبارتی ساده تر منظورتون اینه که چون وقتی یه هسته را فعال کنیم ، بار کاری و مصرف پردازنده میاد پایین و بنابراین خنک تر میشه ، پس فرکانس turbo boost ، به حداکثر مقدارش میرسه . درست میگم؟
اگه آره ، خوب این خلاف چیزی هست که قبلا گفته بودید . قبلا گفتید که با افزایش بار کاری پردازنده (که باعث افزایش مصرف و افزایش دما میشه) ، فرکانس turbo boost بیشتر میشه .

استاد ، خیلی ممنونم که جواب مو دادین