PDA

View Full Version : حلقه بسیار بزرگ



CHAMALZ
یک شنبه 24 فروردین 1393, 17:55 عصر
با سلام. من یک نیاز به یک حلقه خیلی بزرگ دارم حالا فرقی نمیکنه که لوپ باشه یا فور یا هرچی. کار حلقه اینه که یک تابعی که خودم نوشتم را اجرا کنه. و در کل تابع و حلقه کارشون اینه که برای من یک عدد خیلی بزرگ را برمیگردونه و هر دفعه به این عدد اضافه میکنه. به مثال زیر توجه فرمایید:



//my function
string add(string n)
{
------------------
---------------
------------
return AdeddNo;
}


private void button1_Click(object sender, EventArgs e)
{
string n1={4,5,6,7};


while (true)
{
add(n1);
//khoroji bad az avalin ejra mishe 4,5,6,8
//az adad returen shode inja estefade mishe
}
}





حالا مشکل اینه که سرعت برنامه خیلی کمه. از نخ هم نمیشه استفاده کنم چون که میخوام اعداد متوالی باشه و اگر از نخ استفاده کنم باید به نخ اسلیپ (delay) بدم و منتظر بمونه تا خروجی را بگیره و به ورودی نخ بعدی بدهد که در این صورت کارایی برنامه کاهش پیدا میکنه.طول عدد از 1 قم شروع میشه و تا مثلا 7485728942651 رقم میره. آیا روشی وجود داره که با سرعت زیاد این کار انجام بشه ؟من روی یه سرور با سی پیو 8 هسته ای تست کردم ولی سرعتش خیلی خیلی کمه به صورتی که از 1 رقم تا 10 رقم 1 روز طول میکشه چون از همه توان سی پی یو استفاده نمیشه. لطفا راهنمایی کنید.امیدوارم متوجه منظورم شده باشید.با تشکر.

behzadkhan
یک شنبه 24 فروردین 1393, 19:14 عصر
با سلام

منظور از "
1 قم شروع میشه و تا مثلا 7485728942651 رقم میره"

یعنی تعداد ارقام؟
اگه اینجوری که؟

و منظور از جمع کردن چیه؟

همچنین الگوریتم تابع که در هر چرخش اجرا می شه چیه؟

با تشکر

us1234
دوشنبه 25 فروردین 1393, 00:14 صبح
هدفت دقیقا چیه ؟
شاید اگه کامل توضیح بدید تابع بهینه شده است را بشه نوشت و یا جوری با ترد های پیاده سازی کرد به هدف برسید .

دقیق شرح بدید این کد قراره چکاری انجام بده ؟

syntiberium
دوشنبه 25 فروردین 1393, 00:52 صبح
از همون نخ استفاده کن و اگر تعداد اعداد رو می دونی یه آرایه به تعداد اعداد درست کن و اگر نمی دونی از لیست استفاده کن و هر نخ قبل از اینکه شروع بشه به یه شمارنده یکی اضافه کن و به عنوان ورودی تابع وارد نخ کن و اون می شه شماره ی اون نخ و در آخر شماره ی نخ می شه index اون خونه از آرایه که قراره خروجی نخ واردش بشه (اگر از لیست استفاده می کنی قبل از شروع هر نخ یه مقدار خالی به لیست اضافه کن). اینجوری اعداد ترتیبشون حفظ می شه .

CHAMALZ
دوشنبه 25 فروردین 1393, 09:00 صبح
با تشکر از پاسخ دوستان .دقیقا" میخوام که این تابع این کار را برام انجام بدهد:
از عدد 1 تا مثلا چند هزار میلیارد را بهم بر گردونه همین.
1
2
3
4
5
-
-
99999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999

حالا که کامل توضیح دادم لطفا بهترین روش پیاده سازی(بیشترین سرعت) را بهم بگید.با تشکر.

hamid_hr
دوشنبه 25 فروردین 1393, 10:41 صبح
خب به سی پی یو همش مربوط نمیشه که
نمایش اونا زمان میبره

behzadkhan
دوشنبه 25 فروردین 1393, 12:45 عصر
با سلام

اینجور که من متوجه شدم.

مقدار عدد شما در هیچکدام از نوع داده ها جا نمی شد.(
99999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999)

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

با تشکر

rahnema1
دوشنبه 25 فروردین 1393, 13:40 عصر
سلام
شما می تونید از BigInteger استفاده کنید

http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx

us1234
دوشنبه 25 فروردین 1393, 14:14 عصر
با تشکر از پاسخ دوستان .دقیقا" میخوام که این تابع این کار را برام انجام بدهد:
از عدد 1 تا مثلا چند هزار میلیارد را بهم بر گردونه همین.
1
2
3
4
5
-
-
99999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999

حالا که کامل توضیح دادم لطفا بهترین روش پیاده سازی(بیشترین سرعت) را بهم بگید.با تشکر.

حدس میزنم شما دنبال بزرگترین عدد اول میگردید . هدفت را که نمیگی !
ولی اگه سی پی یو که داری استفاده میکنی 8 هسته است یعنی باید 16 تا ترد داشته باشه این را دقیق مشخص کن یا 4 هسته ای است و 8 تا ترد داره . بسته به تعداد تردهای سی پی یو داخل برنامه ات ترد میسازی و priority را هم میذاری بالاترین حدش . ورودی هر ترد را همانطور که دوستان در پست شماره 4 گفت 2 تا ایندکس پاس میدی این ایندکس ها به ترد میفهمونه که از کجا باید شروع کنه و به کجا ختم بشه و در ضمن این حجم زیاد را هم نباید نمایش بدی باید داخل یک دیتابیس سریع مثل Sqlite ذخیره کنی . یعنی هر ترد که تموم شد نتیجه اش را میده به دیتابیس .
وقتی هر 8 ترد تموم شد مین برنامت باید اطلاعات ذخیره شده را نمایش بده . ( تاکید میکنم در هر بار که یک ترد اجرا میشه اطلاعات ذخیره نشود بلکه داخل یک رشته نگهدار تا کار کل ترد تموم شد ذخیره اش کن )
تازه اون حلقه را هم از مین بردار و بذارش توی ترد ها . یعنی همون تابعی که به هر ترد میگی اجراش کنه .
در کل هدف مشخص نیست بهتر از این هم نمیشه راهنمایی کرد.

CHAMALZ
سه شنبه 26 فروردین 1393, 08:42 صبح
با تشکر از دوست عزیز us1234. همانطور که قبلا گفتم میخوام از عدد 1 تا چند میلیارد را یه جای مثل داخل فایل یا دیتابیس ذخیره کنم همه اعداد را میخوام نه زوج یا فرد و یا اول ها را همشون را نیاز دارم. دیگه چطوری هدف را مشخص کنم ؟:گریه:
میشه یه مثال کوچک از این کاری(مشخص کردن با ایندکس) که گفتید بزنید ؟من میخوام تک تک اعداد را ذخیره کنما! با تشکر.

rahnema1
چهارشنبه 27 فروردین 1393, 12:31 عصر
ابتدا به System.Numerics رفرنس بدید

using System.Numerics;
using System.IO;
//...
System.IO.TextWriter ss1 = new StreamWriter("myfile1.txt");
for (BigInteger i = BigInteger.Parse("0"); i < BigInteger.Parse("99999999999999999999999999999999999"); i++) {
ss1.WriteLine((object) i);
}
ss1.Close();

CHAMALZ
چهارشنبه 27 فروردین 1393, 16:17 عصر
با تشکر از پاسخ شما ولی من میخوام که از thread استفاده کنم که سرعت برنامه زیاد بشه و طول عدد تا
7485728942651 رقم باشه که برای طول یک تابع نوشتم با استرینگ مشکلی نیست فقط نمیتونم داخل نخ بزارم.

rahnema1
چهارشنبه 27 فروردین 1393, 20:54 عصر
با فرض اینکه 8 تا cpu داشته باشید میتونید دامنه اعداد را به 8 قسمت تقسیم کنید و مقادیر موجود در 8 دامنه را در 8 فایل جداگانه ذخیره کنید
فقط مشکل سرعت هارد باقی می مونه که برنامه با thread هم فایده ای نداره
مگه اینکه 8 تا هارد داشته باشید و هر فایل توی یک هارد جدا ذخیره بشه

یک نکته دیگه چه لزومی داره این همه داده را ذخیره کنید؟
می دونید فقط نوشتن آخرین عدد توی فایل حدود 7 گیگ جا اشغال می کنه؟
این هم برنامه:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Numerics;

namespace bigint2
{
class Program
{
public static void Write1(BigInteger first,BigInteger last,int num)
{
TextWriter file= new StreamWriter("myfile"+num+".txt");
for (BigInteger i = first; i < last; i++)
file.WriteLine((object) i);
file.Close();
}

static void Main(string[] args)
{
int numcpu =8;
BigInteger last = BigInteger.Parse("99");
for (var i = 1; i < numcpu+1; i++)
{
var val = i;
BigInteger f = last*(i-1)/numcpu;
BigInteger l= last*i/numcpu;
var runningTask = Task.Factory.StartNew(()=>Write1(f,l,val)) ;
}
Console.ReadKey() ;
}
}
}

rahnema1
پنج شنبه 28 فروردین 1393, 06:03 صبح
یک نکته دیگه اضافه کنم تا تصورمون از مساله دقیق تر بشه
اگه فرض کنیم هر رقم 1 بایت اشعال می کنه، کل داده های شما 14971457885302^10*5 بایت جا اشغال می کنه، در حالیکه ادعا میشه بزرگترین دیتا سنتر جهان چیزی بین 18^10 تا 24^10 بیشتر ظرفیت نداره!
این هم منبعش:
http://www.dailydot.com/news/nsa-utah-data-center-capacity-surveillance-storage/