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

نام تاپیک: سوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

Hybrid View

پست قبلی پست قبلی   پست بعدی پست بعدی
  1. #1

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

    سلام
    وقتی از 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 کسی میدونه توضیح بده؟ این ، همون مقدار انتظار یا سربار اون هسته ی منطقی را نمایش میده؟
    آخرین ویرایش به وسیله SajjadKhati : دوشنبه 04 آذر 1398 در 11:09 صبح

  2. #2

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

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

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

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    پردازنده ی من 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 و سیستم مدیریت حافطه و مدیریت فایل و ... رو با چه پردازنده ای اجرا کنه؟


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

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

  3. #3

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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

    نقل قول نوشته شده توسط the king مشاهده تاپیک
    پردازنده کد ماشین رو در دو تا مد اجرا میکنه، یک حالت مد هسته است که به سخت افزار دسترسی مستقیم داره و برنامه های هسته سیستم عامل و درایور ها ازش استفاده می کنند و حالت دوم مد کاربر ئه که به سخت افزار دسترسی مستقیم نداره و برنامه هایی عادی ازش استفاده می کنند. اون چیزی که تحت عنوان kernel time میبینید نشون میده که چه بخشی از کارکرد پردازنده برای اجرا شدن کد های مود هسته صرف شده، یعنی فرضا اگه 20 درصد توان پردازنده باشه، نشون میده 20 درصد توان پردازنده برای اجرا شدن کد های برنامه هسته سیستم عامل و درایور ها صرف شده، نه سایر برنامه های عادی و سیستمی.
    آها خیلی ممنون استاد .
    آخرین ویرایش به وسیله SajjadKhati : دوشنبه 04 آذر 1398 در 16:25 عصر

  4. #4

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

    استاد ، من همین کد (کد اول در پست اول) را در 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 هسته ی منطقی اش هم میشه) را اشغال کرد .

  5. #5

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    استاد ، من همین کد (کد اول در پست اول) را در 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 برابر سریعتر انجام میشه .

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

  6. #6

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

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

  7. #7

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

    نقل قول نوشته شده توسط pe32_64 مشاهده تاپیک
    parallel از thread استفاده میکنه .در اصل همه concurrency api ها از ترد استفاده میکنند.
    ممنون
    بله میدونم
    منتها Parallel که کدها را در هسته ها بصورت همزمان اجرا میکنه ، نمیدونم حالا Thread هم این کار را میکنه یا نه (میخوام اینو بدونم)
    شواهد من نشون میده Thread هم کدها را بصورت همزمان اجرا میکنه (که به استاد ارائه دادم) ولی استاد انگار میگه نمیکنه .
    خودمم گیج شدم چی به چیه .

  8. #8

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    ممنون
    بله میدونم
    منتها Parallel که کدها را در هسته ها بصورت همزمان اجرا میکنه ، نمیدونم حالا Thread هم این کار را میکنه یا نه (میخوام اینو بدونم)
    شواهد من نشون میده Thread هم کدها را بصورت همزمان اجرا میکنه (که به استاد ارائه دادم) ولی استاد انگار میگه نمیکنه .
    خودمم گیج شدم چی به چیه .
    خوب وقتی میدونین دیگه سوال کردنش برا چیه ؟!
    تمام کار ها اخرش ختم میشه به
    Thread ، تمام ! خودتون رو گیچ نکنید.
    ****
    کار اصلی اجرای کد در سیستم عامل با
    Thread هستش.حتی وقتی یک فایل Exe رو باز می کنید براش یک ترد ساخته میشه تا کد برنامه درونش اجرا شه .
    Parallel هم 2 تا ترد میسازه و کد شما رو بش تحویل میده برا اجرا .بعد هم نتیجه کارشون رو میگیره و پس میفرسته. این البته ساده شدست ولی اصول کلیش همین هستش.



  9. #9

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

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

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    استاد ، من همین کد (کد اول در پست اول) را در 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 بهتون نمیگه که چقدر از توان پردازنده رو در حین سوئیچ کردن ها هدر میدید، شما اونها رو جزو کارایی کدتون حساب می کنید چون با اجرای یک نخی پردازنده مقایسه اش می کنید که انگار نخ یکنواخت اجرا میشه.
    در حالی که اگر سرعت اجرای نخ رو با سرعت بالا بررسی می کردیم دائم اجرا متوقف شده بود، این موارد ریز رو سیستم عامل نشون نمیده.

  10. #10

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Preview.png


    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);
    }
    }


  11. #11

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

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

    بازم تشکر

  12. #12

    نقل قول: سئوال درباره ی اجرای چند نخی و استفاده از چند هسته بصورت همزمان

    دوست عزیز
    SajjadKhati
    نخ یا thread پایین ترین سطح api در سیستم عامل رو داره .شما نباید مستقیم ازش در برنامه تون استفاده کنید.
    مثال هاتون بسیار ساده ست و هیچ اطلاعات اشتراکی نداره . برای همین مشکلات فراوان استفاده مستقیم از multi-threading خودشون رو نشون ندادن.
    در محیط net. شما api های بهتری رو داری با سطح abstraction بالا تر و قابلیت استفاده ساده تر.مثل Task Parallel Library که خودش مجموعه ای از api های مفید هستش و به همین منظور ساخته شده .مانند :
    Task-based Asynchronous Programming
    Data Parallelism
    Dataflow

  13. #13

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

    سلامی مجدد
    استاد ، من کدتون را بصورت زیر تغییر دادم ، حتی نتیجه ی معکوس هم داد :


    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);
    }


    }
    }







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


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


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

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

    اگه پست 4 ام رو هم جواب میدادین ، خیلی ممنون میشدم .
    خیلی ممنون که تا اینجا راهنمایی کردین .
    عکس های ضمیمه عکس های ضمیمه
    • نوع فایل: jpg 1.JPG‏ (20.6 کیلوبایت, 121 دیدار)

  14. #14

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    سلامی مجدد
    استاد ، من کدتون را بصورت زیر تغییر دادم ، حتی نتیجه ی معکوس هم داد :


    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);
    }


    }
    }







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


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


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

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

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

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

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


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

  15. #15

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

    اول پروژه ای رو که نوشتم پیوست کنم تا بعد به مسائل مربوطه بپردازیم :

    ProcessThreads.rar

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

    Preview.png

  16. #16

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

    نقل قول نوشته شده توسط the king مشاهده تاپیک
    اول پروژه ای رو که نوشتم پیوست کنم تا بعد به مسائل مربوطه بپردازیم :

    ProcessThreads.rar

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

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

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














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

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

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





    نقل قول نوشته شده توسط the king مشاهده تاپیک
    چند تا فرض اولیه دارید که درست نیستند. اول اینکه پردازنده مشغول پروسه برنامه شما بشه به معنی این نیست که داره با همون توان کد های نخ شما رو اجرا می کنه. فراموش نکنید که برنامه شما در ماشین مجازی قرار داره، بخش قابل توجهی از کاری که پردازنده برای پروسه شما انجام میده صرف تبادل بین ماشین مجازی و حقیقی میشه که اگر این بود سرعت اجرای کد های #C به حد متعارف C++‎‎‎‎‎‎‎‎ Native میرسید.
    که این کدهای clr یا ماشین مجازی را در Task Manager ، در سربرگ Performance ، بصورت Kernel Time مشخص میشه (قبلا گفته بودید) . درسته؟


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

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

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


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


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

    خیلی ممنون استاد از جواب تون
    عکس های ضمیمه عکس های ضمیمه
    • نوع فایل: jpg 2.jpg‏ (93.1 کیلوبایت, 116 دیدار)
    • نوع فایل: jpg 3.jpg‏ (92.8 کیلوبایت, 115 دیدار)
    • نوع فایل: jpg 4.JPG‏ (12.9 کیلوبایت, 115 دیدار)
    آخرین ویرایش به وسیله SajjadKhati : سه شنبه 05 آذر 1398 در 18:14 عصر

  17. #17

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

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    اما من همین برنامه تون را در کامپیوتر خودم اجرا کردم و نتیجه جور دیگه ای هست :




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

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

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

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    میتونم مدل دقیق پردازنده تون را بدونم؟ (اگه دوست دارین بگین)
    Intel Core i7 4700HQ

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    که این کدهای clr یا ماشین مجازی را در Task Manager ، در سربرگ Performance ، بصورت Kernel Time مشخص میشه (قبلا گفته بودید) . درسته؟
    نه کد های ماشین مجازی که نه. اگر Process.GetCurrentProcess().PrivilegedProcessorTim e رو بررسی کنید می بینید که یک زمان ناچیز ئه و با Process.GetCurrentProcess().UserProcessorTime.ToSt ring() قابل مقایسه نیست.
    وقتی نمی تونیم در NET. برنامه مود هسته یا درایو بنویسیم طبعا کد های CLR ای که اجرا می کنیم هم در اون مود نیستند.

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    منظورتون اینه که Task Manager ، مثل عکسی که از برنامه تون فرستادید ، نشون نمیده که همزمان ، فقط یک هسته داره روی پروسه مون پردازش انجام میده؟
    برنامه من هم نشون نمیده. من در مشخصات Thread ام نمی تونم بفهمم کدوم CPU مجازی داره اجراش می کنه، برای همین هم نمیتونم بفهمم چند هسته مشارکت کردن.
    صرفا میتونم از سیستم عامل درخواست کنم که لطفا روی فلان CPU مجازی اجرا کن.

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

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

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

  18. #18

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

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

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


    نقل قول نوشته شده توسط the king مشاهده تاپیک
    از طرف دیگه چرا باید کارایی 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 هسته ی دیگه ام آزاد میبود و دیگه پردازش نخ مربوط به عملیات موس که نباید با مشکل کندی شدید رو به رو میشد .
    آخرین ویرایش به وسیله SajjadKhati : سه شنبه 05 آذر 1398 در 23:17 عصر

  19. #19

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

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

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

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


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

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    و منظورم این بود که اگه کلاس 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.
    از طرف دیگه ما که نمیدونیم چقدر این نخ ها بهم وابسته هستند، نمیدونیم که چقدر به هماهنگی با هم نیاز دارند، از چیزی که در ماشین مجازی میگذره که خبر نداریم. نمیدونیم کدوم کد ها و کدوم نخ های هماهنگ کننده سربار ایجاد می کنند.
    فقط یکسری توصیه هایی اینور و اونور پیدا میشه که شاید کمک کنه برای نوشتن کد های مناسبتر.

  20. #20

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

    ادامه :

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




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

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




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




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




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




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

  21. #21

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

    ادامه :

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

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





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






    در 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 مگاهرتز یا بیشتر) . معمولا لپتاپ ها اختلاف شون خیلی زیاد تر هه .
    عکس های ضمیمه عکس های ضمیمه
    آخرین ویرایش به وسیله SajjadKhati : پنج شنبه 07 آذر 1398 در 20:18 عصر

  22. #22

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

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    در 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 هم تداخلی در محاسبات نداره دیگه برای کاهش کارایی شون چه دلیلی دارید؟

تاپیک های مشابه

  1. پاسخ: 1
    آخرین پست: چهارشنبه 13 بهمن 1395, 00:04 صبح
  2. پاسخ: 3
    آخرین پست: دوشنبه 27 خرداد 1392, 12:26 عصر
  3. سوال : ساخت پایگاه داده بصورت تک فایل مستقل بدون پسورد ؟!
    نوشته شده توسط mf.designing در بخش امنیت در SQL Server
    پاسخ: 2
    آخرین پست: پنج شنبه 29 فروردین 1392, 17:09 عصر

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

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