Wielowątkowość (biblioteka thread)

0

Witam,
Programuję swoją własną aplikacje testującą komputer w VS 2013 i mam problem z obsługą wielowątkowości.
W tym momencie (uczę się samodzielnie) korzystam z biblioteki standardowej thread.
Czy istnieje możliwość przypisania kilku wątkom, liczenie i wykonywanie kodu jednej funkcji? (te same polecenia, te same argumenty)
Przykładowo:
Jeśli do wykonywania tego kodu:

{
    long int ilosc = 0;

    for (long long int n = 1; n <= 75000000; n++)
    {
        if (czy_pierwsza(n))
        {
            ilosc++;
        }
        else
        {
            continue;
        }
    }
    //cout << "\nZnaleziono " << ilosc << " liczb pierwszych z zakresu od 1 do 75 000 000.";
}

bool czy_pierwsza(unsigned long int n)
{
    unsigned long int q, r, d;

    if (n < 3 || (n & 1) == 0)
        return n == 2;

    for (d = 3, r = 1; r != 0; d += 2)
    {
        q = n / d;
        r = n - q * d;
        if (q < d)
            return true;
    }
    return false;
} 

na liczby pierwsze spróbuje przypisać więcej niż jeden wątek to aplikacja albo się wiesza albo działa bardzo wolno.
Czy da się coś wymyślić aby np ten kod wykonywało 8 wątków?
Dziękuję z góry za informacje.
Pozdrawiam.

0
  1. Czy słyszałeś o czymś takim jak Sito Eratostenesa?
  2. Pokaż jak to zrobiłeś z tymi wątkami.
0

Słyszałem o tym alg., lecz w moim programie nie piszę tylko obliczania liczb pierwszych tylko różnej maści obliczenia (np. silnie, ciąg Fibonacciego czy potęgowanie liczb do 1000 potęgi), najzwyczajniej w świecie z niego zrezygnowałem. Wszystkie obliczenia chciałbym wykonywać na 8 wątkach.

Wątki próbowałem wprowadzać komendami (dopiero zaczynam z wielowątkowością, proszę o wyrozumialość):

    thread t1(fun), t2(fun), t3(fun), t4(fun), t5(fun), t6(fun), t7(fun), t8(fun); //udawało mi się tym uzyskać 100% narzutu na procesor (i7 3770k)
	t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join(); t7.join(); t8.join);

Wymyśliłem w między czasie, żeby dla każdego wątku przydzielić wyszukiwanie liczb pierwszych na zakresach (np. Wątek pierwszy do 1 do 10000, Wątek drugi od 10001 do 20000 itd.) Czy takie coś ma sens? Czy jest lepszy sposób na wielowątkowość?

Dzięki za odpowiedź.
Pozdrawiam.

0

W podanych dwóch wierszach kodu nie ma błędów.

0

Dobra, czyli jest możliwe, aby kilka wątków korzystało z jednej zmiennej, wykonywało te same linijki kodu i nie było problemów?

1

Jeżeli funkcji wątków nie korzystają z wspólnych zmiennych to nie ma problemu.
Wszystkie zmienne lokalne w funkcjach to nie są wspólne zmienne.
Przy użyciu wspólnych zmiennych potrzebna jest synchronizacja.

2

Zrobiłeś 8 wątków i każdy liczy dokładnie to samo? W jaki sposób to ma cokolwiek przyśpieszyć?

Każdy wątek ma wykonywać to samo, ale na innych danych - tzn dane muszą być rozdzielone pomiędzy wątki. Tylko tak możesz uzyskać przyśpieszenie. W Twoim przypadku każdy wątek musi mieć inny zakres, w którym szuka tych liczb - powinieneś go podawać jako parametr w konstruktorze std::thread.

Poza tym to niemądre - do tego służy sito jak napisał @_13th_Dragon.

1

Pomijając algorytm, skorzystaj z globalnych wartości dla wątków (mechanizm TLS) - http://msdn.microsoft.com/en-us/library/4ax54352(VS.71).aspx

Co do efektywnego wykorzystania wątków to polecam Thread Pools - http://msdn.microsoft.com/en-us/library/windows/desktop/ms686760(v=vs.85).aspx

0

Dziękuję za odpowiedzi. Rozjaśniły mi znacznie sprawę. Mógłbym jeszcze prosić o wyjaśnienie i łatwy przykład jak uzyskać synchronizację wątków (najlepiej w bibliotece thread)?
Pozdrawiam.

0

Dziękuję :)

1

Jeżeli piszesz w VC++ to prościej jest użyć biblioteki ppl i dedykowanej pętli parallel_for.

#include <ppl.h>
using namespace concurrency;

parallel_for(1, 75000000, [&](int n) 
{
});
 
0

A czy jest możliwe żeby tak skonfigurować wątki aby gdy jeden wątek coś liczy i komputer przydziela moc kolejnemu to żeby kolejny kontynuował obliczenia itd?

0

To się nazywa “join” (czekanie na zakończenie innego wątka) i metody o takiej nazwie szukaj, ale taki przypadek o jakim piszesz nie ma sensu - po co ma inny wątek kontynuować obliczenia, skoro może kontynuować ten sam?

0

Przykładowo jesli wykonuje obliczenia na 8 wątkach to pierwszy kończy swoją część po kilku sekundach a każdy kolejny wątek coraz później. W tym przypadku 100% narzutu na procesor uzyskuje tylko przez kilka sekund a później narzut się zmniejsza. A właśnie zależy mi na ciągłym narzucie 100%...
Oczywiście używam poleceń 'join'.

2

Jeżeli zadania dla wątków różnią się czasem wykonania to podziel zadanie na więcej niż 8 części. Gdy jakiś wątek szybciej zakończy swoje zadanie to zostanie mu przydzielone nowe.
Jeżeli zaś zadanie jest u Ciebie podzielone na więcej niż 8 części to oznacza, że nieoptymalnie przydzielasz zadania dla wątków.

0

Dziękuję za dobry pomysł. Z pewnością go przetestuje.

0

wyskakuje mi dziwny błąd... Ktoś może wie co z nim zrobić?
error C2064: term does not evaluate to a function taking 0 arguments C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap 58

Dotyczy tych linijek:

bool czy_pierwsza(unsigned long int n)
	{
		unsigned long int q, r, d;

		if (n < 3 || (n & 1) == 0)
			return n == 2;

		for (d = 3, r = 1; r != 0; d += 2)
		{
			q = n / d;
			r = n - q * d;
			if (q < d)
				return true;
		}
		return false;
	}

	int t1(long int p, long int q)
	{
		long int ilosc = 0;
		for (long long int p; p <= q; p++)
		{
			if (czy_pierwsza(p))
			{
				ilosc++;
			}
			else
			{
				continue;
			}
		}
	}

..............

	for (long int p = 1; p < 12000000; p+=100000)
		{
			for (long int q = 100000; p < 12000000; q+=100000)
			{
				thread th1(t1(p, q));
			}
		}

Dziękuję za pomoc.

0

Czego się spodziewasz w tym wierszu: thread th1(t1(p, q));
Odpalasz funkcje t1 po czym jej wynik przekazujesz do konstruktora wątku, WTF?
Z tych 3-ch wierszy:

    for (long int p = 1; p < 12000000; p+=100000)
        {
            for (long int q = 100000; p < 12000000; q+=100000)

oraz z tych 3-ch:

            else
            {
                continue;

wnioskuje: - zostaw na razie wątki i zajmij się rzeczami prostymi, jeszcze nawet zwykłych pętli nie opanowałeś.

Jak na razie wielowątkowość jest dla ciebie zbyt górnolotnym tematem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1