Permalänk

Lottorader c#

Hej!

Läser just nu programmering 1 på gymnasiet. Vi håller nu på med en slutuppgift för konsollprogrammering (c#). Mitt projekt är ett program som du matar in en lottorad i (sju tal, inga tilläggsnummer). Denna raden kontrolleras sedan mot slumpade rader och räknar lite på sannolikhet. Programmet har två lägen:

1. Jämför din inmatade lottorad mot ett bestämt antal slumpade rader (ex. vis enmiljon stycken). Programmet talar sedan om för dig hur många gånger du fick 5, 6 samt 7 rätt.

2. Välj hur många rätt din egna rad ska ha gentemot slumpade rader. Loopa programmet tills det valda antalet rätt uppkommer, skriv ut hur många varv som krävdes.

Enligt sannolikhetsberäkningar (ex http://www.matteboken.se/lektioner/matte-1/ovningsexempel/lotto) bör man få 7 rätt var 6 700 000:e gång. Detta stämmer relativt bra mot vad båda lägena i mitt program visar (har tagit medelvärde på 1000 mätningar). Problem uppstår dock när man kollar på 6 eller 5 rätt, programmet ger ett resultat som visar att antalet 5 och 6 rätt är betydligt högre än vad som förväntas. Ex.vis om jag jämför min rad med 18 000 andra rader säger sannolikhetsberäkningarna att jag borde få 5 rätt en gång. Detta är inte resultatet. Programmet visar istället att jag får 5 rätt ungefär 15 gånger (även här har jag loopat och räknat medelvärde för att undvika tillfälligheter).

Programmet är uppbyggt så att det slumpar ett tal, kontrollerar så det inte finns tidigare i den slumpade lottoraden, kollar om det slumpade talet finns i min lottorad. Om talet finns i min lottorad ökar en variabel med ett. När alla sju tal i en rad är testade kollar den vad variablen visar. Om variablen visar ex. vis 5 rätt ökar en variabel för fem rätt med ett. När allt är klart skrivs resultatet ut. Den slumpade lottoraden och räknaren för antal rätt per slumpad lottorad nollställs mellan varven.

Någon som har en bra idé om vad felet kan vara?

Permalänk
Keeper of Traditions
Skrivet av erjosefsson:

Någon som har en bra idé om vad felet kan vara?

Du kommer antagligen kunna få mer, och bättre, hjälp om du visar din kod. Om den är väldigt lång så kan Pastebin.com vara en bra idé.

Visa signatur

|| Intel 8700K || Asus RTX 4070 TI Super TUF || Samsung 750 EVO 500GB & Kingston A2000 1TB & Samsung 960 EVO 250GB || Corsair RM 850x || Antec P183 || Asus G-Sync RoG Swift PG279Q || Dell XPS 15 || Thinkpad X220

The Force is like Duct Tape, it has a light side, a dark side, and holds the universe together.

Permalänk
Medlem

Du kan inte lägga alla tal i en lista, sen när du tagit det talet ta bort från listan. Och slumpa från listan?
Dvs du kommer aldrig få samma tal flera gånger, det borde snabba upp och ge en mer korrekt slump-metod.

Men pasta din kod så kan vi se om det är några uppenbara fel etc.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Skrivet av NoPaiN^:

Du kan inte lägga alla tal i en lista, sen när du tagit det talet ta bort från listan. Och slumpa från listan?
Dvs du kommer aldrig få samma tal flera gånger, det borde snabba upp och ge en mer korrekt slump-metod.

Men pasta din kod så kan vi se om det är några uppenbara fel etc.

Skrivet av Newklear:

Du kommer antagligen kunna få mer, och bättre, hjälp om du visar din kod. Om den är väldigt lång så kan Pastebin.com vara en bra idé.

Koden:

{ //Deklaration av variabler char fortsätta = 'j'; char sammaLottorad = 'n'; short valMeny1 = 0; short valMeny2 = 0; short[] lottorad = new short[7]; short inmatatLottotal = 0; int jämförelseTermer = 0; int[] jämförelseRader = new int[7]; int jämförelseRaderTal = 0; short räknareAntalRättPerRad = 0; int[] antalRätt = new int[3]; short antalRättVal2 = 0; int varvVal2 = 0; bool giltligRad = true; bool klarVal2 = false; //Nytt random-objekt Random r = new Random(); while (fortsätta == 'j') //Gör att man senare kan välja om man vill köra programmet igen { //Menyval Console.Clear(); //Rensa konsollen, användbart om programmet körs flera gånger utan att stänga fönstret Console.WriteLine("Välj vad du vill göra i menyn nedan."); Console.WriteLine("1. Jämför egen lottorad mot andra och se antal rätt"); Console.WriteLine("2. Undersök hur många dragningar som krävs för att få ett visst antal rätt"); valMeny1 = short.Parse(Console.ReadLine()); //Inmatning av lottorad if (sammaLottorad == 'n') //Gör så att man kan använda samma lottorad flera varv { Console.WriteLine("Ange din lottorad:"); for (int i = 0; i < lottorad.Length; i++) { Console.Write("Nummer {0}: ", (i + 1)); inmatatLottotal = short.Parse(Console.ReadLine()); //Gör att man ej kan ange samma tal flera gånger per lottorad eller ange tal större än 35 if (inmatatLottotal == lottorad[0] || inmatatLottotal == lottorad[1] || inmatatLottotal == lottorad[2] || inmatatLottotal == lottorad[3] || inmatatLottotal == lottorad[4] || inmatatLottotal == lottorad[5] || inmatatLottotal == lottorad[6] || inmatatLottotal > 35) { giltligRad = false; } lottorad[i] = inmatatLottotal; //Sparar till variabeln lottorad } //Om raden ej var giltlig if (giltligRad == false) { Console.WriteLine("Lottorad är ej giltlig."); Console.WriteLine("Samma värde får ej förekomma mer än en gång och högsta tillåtna tal är 35."); sammaLottorad = 'n'; } } if (giltligRad == true) //Gör att programmet endast kan gå vidare om den inmatade lottoraden var giltlig { if (valMeny1 == 1) //Valet i den första menyn verkställs { Console.WriteLine("Hur många rader vill du jämföra mot? Ange nummret på alternativet nedan."); Console.WriteLine("1. 10 000 stycken"); Console.WriteLine("2. 100 000 stycken"); Console.WriteLine("3. 1 000 000 stycken"); Console.WriteLine("4. 10 000 000 stycken"); Console.WriteLine("5. Ange eget värde"); valMeny2 = short.Parse(Console.ReadLine()); //Låter användaren välja hur många rader man ska jämföra mot switch (valMeny2) { case 1: { jämförelseTermer = 10000; break; } case 2: { jämförelseTermer = 100000; break; } case 3: { jämförelseTermer = 1000000; break; } case 4: { jämförelseTermer = 10000000; break; } case 5: { Console.WriteLine("Ange antalet rader nedan:"); //Gör det möjligt att ange ett eget värde för antalet rader att jämföra mot jämförelseTermer = int.Parse(Console.ReadLine()); break; } } //Beräkningen av antalet rätt for (int i = 0; i < jämförelseTermer; i++) //Kör slingan lika många varv som valdes ovan { for (int q = 0; q < 7; q++) //Slinga som kör sju varv, ett varv för varje tal i enskild lottorad som jämförs mot { jämförelseRaderTal = r.Next(1, 36); //Skapar ett random-tal 1 ≤ x ≤ 35 //Jämför talet med tidigare tal i lottoraden. Om talet förekommer tidigare i raden ersätts det med ett annat while (jämförelseRaderTal == jämförelseRader[0] || jämförelseRaderTal == jämförelseRader[1] || jämförelseRaderTal == jämförelseRader[2] || jämförelseRaderTal == jämförelseRader[3] || jämförelseRaderTal == jämförelseRader[4] || jämförelseRaderTal == jämförelseRader[5] || jämförelseRaderTal == jämförelseRader[6]) { jämförelseRaderTal = r.Next(1, 36); } //Talet jämförs med den inmatade lottoraden. Om talet matchar något av talen i den ökar variablen med ett if (jämförelseRaderTal == lottorad[0] || jämförelseRaderTal == lottorad[1] || jämförelseRaderTal == lottorad[2] || jämförelseRaderTal == lottorad[3] || jämförelseRaderTal == lottorad[4] || jämförelseRaderTal == lottorad[5] || jämförelseRaderTal == lottorad[6]) { räknareAntalRättPerRad++; } jämförelseRader[q] = jämförelseRaderTal; //Sparar talet till jämförelseRader. Talet får samma plats som varvet i loopen. } //Räknar antalet rätt switch (räknareAntalRättPerRad) { case 5: //Om antal rätt = 5 ökar variabeln med ett { antalRätt[0]++; break; } case 6: //Om antal rätt = 6 ökar variabeln med ett { antalRätt[1]++; break; } case 7: //Om antal rätt = 7 ökar variabeln med ett { antalRätt[2]++; break; } } räknareAntalRättPerRad = 0; //Nollställer räknaren för antal rätt per rad //Nollställer raden som jämförelsen sker mot for (int k = 0; k < jämförelseRader.Length; k++) { jämförelseRader[k] = 0; } //Skriver ut punkter som indikerar att programmet räknar om talet är 10 000 eller större if (jämförelseTermer >= 10000) { if (i % (jämförelseTermer / 20) == 0) //Om varvet i loopen går att dela med en tjugondel av raderna som man jämför mot utan att få någon rest, skrivs en punkt ut { Console.Write("."); } } } Console.WriteLine(); //Radbryt efter punkterna //Skriver ut resultatet Console.WriteLine("Rättat mot {0} rader, hade du sju rätt {1} gång(er), sex rätt {2} gång(er) och fem rätt {3} gång(er).", jämförelseTermer, antalRätt[2], antalRätt[1], antalRätt[0]); } DEL 2 AV PROGRAMMET. EJ PROBLEMET. } //Möjliggör att användaren kan köra programmet igen Console.WriteLine("Vill du köra programmet igen (fönstret kommer att rensas)? (j/n)"); fortsätta = char.Parse(Console.ReadLine()); //OM användaren vill köra programmet igen ställs frågan om samma lottorad ska användas if (fortsätta == 'j') { if (giltligRad == true) { Console.WriteLine("Vill du använda samma lottorad? (j/n)"); sammaLottorad = char.Parse(Console.ReadLine()); } //Om användaren vill ange en ny lottorad nollställs den förra if (sammaLottorad == 'n') { for (int i = 0; i < 7; i++) { lottorad[i] = 0; } } klarVal2 = false; //Nollställer loopen för val 2 i den första menyn (jämföra raden till man får ett visst antal rätt giltligRad = true; //Möjliggör att en ny rad kan betraktas som giltlig, annars blir ägven en giltlig rad sedd som ogiltlig //Nollställer räknaren för antal rätt per antal rätt (ex. vis hur många 5 rätt) for (int o = 0; o < antalRätt.Length; o++) { antalRätt[o] = 0; } } } Console.ReadLine(); } } }

Dold text
Permalänk
Medlem

Som jag sa innan försök använda en lista?
Sen försök att bryta ut koden i metoder/procedurer, underlättar för läsning och debugging.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Skrivet av NoPaiN^:

Som jag sa innan försök använda en lista?
Sen försök att bryta ut koden i metoder/procedurer, underlättar för läsning och debugging.

Hur menar du med en lista

EDIT: Menar du http://www.csharpskolan.se/showarticle.php?id=75#Exempel1:List3? Under list?

Hittade kanske en lösning
Permalänk
Medlem
Skrivet av erjosefsson:

Hur menar du med en lista

EDIT: Menar du http://www.csharpskolan.se/showarticle.php?id=75#Exempel1:List3? Under list?

Ja precis, du gör en metod som reseta din lista, alltså fyller listan med alla tal.
Sen kör du en random från start till slut på listan, ta ut talet och ta bort talet från listan.
Sen när du är klar kan du reseta listan, och köra igen osv.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Skrivet av NoPaiN^:

Ja precis, du gör en metod som reseta din lista, alltså fyller listan med alla tal.
Sen kör du en random från start till slut på listan, ta ut talet och ta bort talet från listan.
Sen när du är klar kan du reseta listan, och köra igen osv.

Tack ska kolla på detta senare ikväll. Återkommer med resultat

Permalänk
Medlem

Sen har du lite småfel här och var men kanske inte påverkar resultatet.
Tex. där användaren ska skriva in ett tal, där borde det vara en whileloop?

for (int i = 0; i < lottorad.Length; i++) //Borde vara typ while(antalKorrektaTal == 7)

Kan du skippa en hel del annat i koden.

Tips på en del metoder som du kan göra och bryta ut koden med.

void generateAllNumbers(vector<int> &allNumbers) //Här generar du alla tal som ska slumpas, kan användas för att reseta alla tal också.
int getRandomNumber(vector<int> allNumbers) // Hämta ett slumpat tal och ta bort talet från "listan".
bool checkIfValidNumber(vector<int> currentNumbers, int choicedNumber) //Kollar om inmatad tal redan finns sen tidigare, om inte lägg till i listan.
int menuStart() //Utskrift av meny.
void enterNumber(vector<int> &myNumbers) // utskrift och hantering av inskrivning av tal, anropar i sin tur checkIfValidNumber.
int menuTerm() //Hantering av jämförelseterm och utskrift.
int calculateMatches(vector<int> myNumbers) // Beräknar och hanterar antalrätt.
void resetAll() // Cleara och resetar variabler listor och dylikt.
int menuAgain() //Utskrift och hantering om användaren ska köra samma rad igen, kan anropa resetAll.

Nu säger jag inte att detta är det bästa sättet eller att du ska göra så här, men kanske kan hjälpa dig att bryta ut koden.
Försök iframtiden att inte använda åäö i variabler och dylikt, försök alltid hålla dig till engelska.

Hoppas detta hjälper dig lite

MVH NP^

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk

Nu har jag provat att använda mig av list. Får samma resultat som förut.

Började felsöka på en lite mer seriös nivå genom att skriva ett program som använder exakt samma metod som det andra, när det kommer till att generera slumpade lottorader. När jag kör det får jag följande resultat:

Detta visar att det inte är något fel på metoden som används för att slumpa raderna, eftersom antalet gånger som en siffra förekommer skiljer väldigt lite, sett till det stora hela.

Permalänk
Medlem

Vad jag menade med lista var att du faktiskt slipper slumpa tal som redan är tagna, vilket leder till bättre prestanda.
Sen känns det ju mer korrekt i mina öron, finns säkert nån formel för det. (Men jag kan ha fel).
Men att du får bättre prestanda är ju uppenbart.

Jag skrev ihop ett program på jobbet idag, kan kolla vad jag får där imorgon.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem

Okej då har jag skrivit ett program, med lite olika funktionalitet.
Kan hantera unika/icke unika rader, trådat, varje tal i rätt ordning, inte i rätt ordning etc.
Och jag verkar få det att stämma, tror du också ha rätt.

Om du tar en titt här, så ser du att 5 rätt 1:847
https://svenskaspel.se/?pageid=/turspel/lotto/information

Verkar ju som dom gjort nåt tabbe där du länka, övrigt verkar det stämma.
Hoppas det hjälper dig

MVH NP^

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem

Har har du lite info som jag tagit ut.
10 miljoner rader ger ett medelvärde på:
Fem rätt= 11893
Sex rätt= 303
Sju rätt= 1

Och det tycker jag verkar rimligt.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Datavetare
Skrivet av NoPaiN^:

Okej då har jag skrivit ett program, med lite olika funktionalitet.
Kan hantera unika/icke unika rader, trådat, varje tal i rätt ordning, inte i rätt ordning etc.
Och jag verkar få det att stämma, tror du också ha rätt.

Om du tar en titt här, så ser du att 5 rätt 1:847
https://svenskaspel.se/?pageid=/turspel/lotto/information

Verkar ju som dom gjort nåt tabbe där du länka, övrigt verkar det stämma.
Hoppas det hjälper dig

MVH NP^

Kunde inte heller låta bli att skriva ett program för detta. Problemet i sig är ju embarrassingly parallel men insåg att det fanns rätt många hål man kunde kliva i när man kör detta på flera CPU-trådar.

Hur delade du upp problemet och hur lade du ihop resultaten från varje tråd? Hur många rader kan du räkna per sekund? Vilket språk?

Den version jag totade ihop i C kan "rätta" och räkna antal gånger varje nummer förekommit på 20M rader per sekund på en Core i7 2600 och 80M rader per sekund på en dual Xeon E5-2680 (16 CPU-kärnor, 32 trådar). Går säkert att pressa upp detta mer, målet var att få det att skala på många CPU-kärnor vilket det gör nu.

time ./lotto < row.txt Nummer 1: 2 Nummer 2: 8 Nummer 3: 19 Nummer 4: 27 Nummer 5: 5 Nummer 6: 7 Nummer 7: 9 Nummer : 1 Antal gånger : 160007254 Nummer : 2 Antal gånger : 159986811 Nummer : 3 Antal gånger : 160035465 Nummer : 4 Antal gånger : 160002059 Nummer : 5 Antal gånger : 159989753 Nummer : 6 Antal gånger : 159988746 Nummer : 7 Antal gånger : 160012041 Nummer : 8 Antal gånger : 160010508 Nummer : 9 Antal gånger : 160005607 Nummer : 10 Antal gånger : 160006892 Nummer : 11 Antal gånger : 159998024 Nummer : 12 Antal gånger : 159995347 Nummer : 13 Antal gånger : 159986828 Nummer : 14 Antal gånger : 160004759 Nummer : 15 Antal gånger : 159986961 Nummer : 16 Antal gånger : 159992458 Nummer : 17 Antal gånger : 159991157 Nummer : 18 Antal gånger : 160016597 Nummer : 19 Antal gånger : 159998134 Nummer : 20 Antal gånger : 159999885 Nummer : 21 Antal gånger : 160002215 Nummer : 22 Antal gånger : 159994649 Nummer : 23 Antal gånger : 159995435 Nummer : 24 Antal gånger : 160004099 Nummer : 25 Antal gånger : 159992189 Nummer : 26 Antal gånger : 159995336 Nummer : 27 Antal gånger : 159995465 Nummer : 28 Antal gånger : 159994725 Nummer : 29 Antal gånger : 160002237 Nummer : 30 Antal gånger : 160003280 Nummer : 31 Antal gånger : 159994015 Nummer : 32 Antal gånger : 159999167 Nummer : 33 Antal gånger : 160006996 Nummer : 34 Antal gånger : 160005130 Nummer : 35 Antal gånger : 159999776 Rättat mot 800000000 rader, hade du sju rätt 96 gång(er), sex rätt 23697 gång(er) och fem rätt 940874 gång(er) real 0m3.206s user 1m41.806s sys 0m0.000s

Dold text

Edit: hade glömt en debug pryl i koden... Det ska vara 250M rader per sekund på Xeon maskinen och 70M rader per sekund på Core i7 2600.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem

Om första två variablerna endast är ja och nej så kan dessa vara bool istället.

Visa signatur

FreeNAS 3U | 8GB | 2x2x3TB ProxMox i7-8700K | 32GB Desktop Dell 22" | Benq 22" | i5-smth | 16GB | Intel 520 120GB | 500GB | Arch

Permalänk
Skrivet av NoPaiN^:

Okej då har jag skrivit ett program, med lite olika funktionalitet.
Kan hantera unika/icke unika rader, trådat, varje tal i rätt ordning, inte i rätt ordning etc.
Och jag verkar få det att stämma, tror du också ha rätt.

Om du tar en titt här, så ser du att 5 rätt 1:847
https://svenskaspel.se/?pageid=/turspel/lotto/information

Verkar ju som dom gjort nåt tabbe där du länka, övrigt verkar det stämma.
Hoppas det hjälper dig

MVH NP^

Skrivet av NoPaiN^:

Har har du lite info som jag tagit ut.
10 miljoner rader ger ett medelvärde på:
Fem rätt= 11893
Sex rätt= 303
Sju rätt= 1

Och det tycker jag verkar rimligt.

Tack så mycket för hjälpen! Har testkört lite nu och mitt program verkar fungera bra jämfört med Svenska Spels statistik. Ska försöka modifiera programmet lite imorgon så jag kan köra det riktigt många varv och få ut ett bra medelvärde.

Skrivet av atriix:

Om första två variablerna endast är ja och nej så kan dessa vara bool istället.

Bra tips! Ska kolla på detta

Permalänk

Har nu jämfört mot den "nya" statistiken och mina resultat stämmer mycket bra.

Har dock en sista fråga. Finns det något sätt att få programmet att utnyttja samtliga kärnor i datorn? Exempelvis att programmet läser av antalet kärnor när det startar och sedan utnyttjar samtliga. Det är otroligt frustrerande att sitta och vänta på att den ska räkna (nu när jag test-kör kan det handla om 4-5 timmar) samtidigt som CPU:n belastas antingen 25 eller 50 % (skoldatorn är två-kärnig).

Permalänk
Medlem
Skrivet av Yoshman:

Kunde inte heller låta bli att skriva ett program för detta. Problemet i sig är ju embarrassingly parallel men insåg att det fanns rätt många hål man kunde kliva i när man kör detta på flera CPU-trådar.

Hur delade du upp problemet och hur lade du ihop resultaten från varje tråd? Hur många rader kan du räkna per sekund? Vilket språk?

Den version jag totade ihop i C kan "rätta" och räkna antal gånger varje nummer förekommit på 20M rader per sekund på en Core i7 2600 och 80M rader per sekund på en dual Xeon E5-2680 (16 CPU-kärnor, 32 trådar). Går säkert att pressa upp detta mer, målet var att få det att skala på många CPU-kärnor vilket det gör nu.
.

Tja igen, jag har gjort en del olika versioner, jag skriver i C/C++, jag har gjort en version som klarar cirkus 100M på en halv sekund på en duo 8500.
Det roliga är att den versionen inte är trådad heller, använder sig av 64bitars int som jag lagrar varje tal i varje bas så att säga.

Jag använder mig av olika metoder för att hantera med trådat i övriga versioner, gjorde dessutom en egen randomfunktion för vanliga rand inte är trådsäker och inte tillräckligt snabb. Provade med en del i nya random "c++11" men fick inte riktigt nån speed med dom jag testade.
Annars så låter jag varje tråd lagra sin egen information så att man slipper sync problem och använda mutex och bök

Rolig liten övning faktiskt

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Datavetare
Skrivet av NoPaiN^:

Tja igen, jag har gjort en del olika versioner, jag skriver i C/C++, jag har gjort en version som klarar cirkus 100M på en halv sekund på en duo 8500.
Det roliga är att den versionen inte är trådad heller, använder sig av 64bitars int som jag lagrar varje tal i varje bas så att säga.

Jag använder mig av olika metoder för att hantera med trådat i övriga versioner, gjorde dessutom en egen randomfunktion för vanliga rand inte är trådsäker och inte tillräckligt snabb. Provade med en del i nya random "c++11" men fick inte riktigt nån speed med dom jag testade.
Annars så låter jag varje tråd lagra sin egen information så att man slipper sync problem och använda mutex och bök

Rolig liten övning faktiskt

Att rand() inte är trådsäker beror på implementation. Det var ett av problem jag hade med min version, den skalade bra på OSX men skalade inte alls på Linux. Visade sig att OSX inte skyddar "seed" värdet på något sätt, vilket gör att man inte får något problem med skalbarheten men man har ju faktiskt en bug...

Orkade inte skriva en egen rand funktion, men det visade sig att både OSX och Linux hade rand_r() som man kan göra trådsäker genom att ha separata "seed" värden för varje tråd, så körde med den.

Verkar som vi har exakt samma lösning i övrigt: separata variabler för varje tråd och aggregera resultatet på slutet. Det man kan råka ut för i den lösningen är "false-sharing", testade att skapa detta problem och mycket riktigt så dök skalbarheten rejält, dock inte lika illa som att ta/släppa en mutex per anrop till rand() som skedde i Linux (korrekta) implementation.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer