CPU

1. CPU

Antonio Donato Filho
Donato100

(usa Ubuntu)

Enviado em 30/01/2018 - 14:31h

Ola.
Gostaria que alguem me ajuda-se a criar uma linha de comando para que um codigo usa-se 4 nucleos da CPU como este:
nice ./factor -cpu 0:3 &
O codigo que estou usando é este | https://rosettacode.org/wiki/Lucas-Lehmer_test#C | já instalei a Biblioteca GMP e compilei com exito g++ mersenne.c -o mersenne.o -L/gmp_install/lib -lgmp
Mais ./mersenne -cpu 0:3 & naõ funcionou.
Antecipadamnte agradeço a que puder ajudar.



  


2. Re: CPU

Fernando
phoemur

(usa Debian)

Enviado em 30/01/2018 - 18:14h

O código que você está usando não permite execução assíncrona, não existe uma linha de comando que vai fazê-lo rodar em todos os núcleos ao mesmo tempo.

Teria que mudar o código... Mas não é difícil de fazer...


3. Re: CPU

Antonio Donato Filho
Donato100

(usa Ubuntu)

Enviado em 30/01/2018 - 18:19h

Como seria?
Lembrando que sou leigo em C.


4. Re: CPU

Hugo Fernandes
Hgfs

(usa Arch Linux)

Enviado em 30/01/2018 - 19:20h

OpenMP é bem simples de implementar. Dá uma procurada aí.


5. Re: CPU

Fernando
phoemur

(usa Debian)

Enviado em 30/01/2018 - 20:27h

Aqui eu fiz uma abordagem mais simples (porém menos eficiente) dos primos mersenne com o teste de lucas_lehmer para que você possa entender.
Utilizei Boost::Multiprecision / GMP e a própria interface de multithreading do C++.
Provavelmente você já tem boost no seu linux instalado default.
Veja como não é complicado:


// g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread
#include <iostream>
#include <vector>
#include <future>
#include <boost/multiprecision/gmp.hpp>

using namespace boost::multiprecision;

// returns 2^exp - 1
mpz_int power(const uint64_t exp)
{
mpz_int number = 2;
for (uint64_t i = 1; i < exp; ++i) {
number *= 2;
}

number--;

return number;
}

// Performs LL test for exp if exp is odd
bool lucas_lehmer(uint64_t exp,
const mpz_int& number)
{
// corner cases
if (exp == 2) {
std::cout << "//**" << number << "**//\n\n";
return true;
}
else if (exp%2 == 0) return false;

// main calc
mpz_int s = 4;

while (exp > 2) {
s = (s*s - 2) % number;
exp--;
}

if (s == 0) {
std::cout << "//**" << number << "**//\n\n";
return true;
}
else return false;
}

auto async_worker(const uint64_t n)
{
std::vector<std::future<bool>> fut;
fut.reserve(n);

for (uint64_t i = 1; i<=n; ++i) {
fut.push_back(std::async(lucas_lehmer, i, power(i)));
}

return fut;
}


int main(int argc, char* argv[])
{
uint64_t n = 43112609;
if (argc > 1) n = std::stoul(argv[1]);

auto vec = async_worker(n);

for (auto& i: vec) {
i.get();
}


return 0;
}


Como estão sendo executadas várias threads ao mesmo tempo, é possível que imprima fora de ordem ou um número em cima do outro, e por isso eu coloquei pra imprimir //** **// antes e depois.
Verifique que vai estar rodando com todos os núcleos...

Resultado parcial aqui:

[phoemur@notebook_lenovo.darkstar ~/teste/teste/teste]$g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread
[phoemur@notebook_lenovo.darkstar ~/teste/teste/teste]$./mersenne
//**3**//

//**//**//**31**//

7**//

127**//

//**8191**//

//**131071**//

//**524287**//

//**2147483647**//

//**2305843009213693951**//

//**618970019642690137449562111**//

//**162259276829213363391578010288127**//

//**170141183460469231731687303715884105727**//

//**6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151**//



6. CPU [resolvido]

Antonio Donato Filho
Donato100

(usa Ubuntu)

Enviado em 30/01/2018 - 20:36h

Genial.
Mais ainda tenho uma dificuldade que é a biblioteca iostream.

donato@donato:~/Área de Trabalho/mersenne/src/objt$ gcc m.c -o m
m.c:3:20: fatal error: iostream: Arquivo ou diretório não encontrado
compilation terminated.
Encontrei este blog e usei o codigo fonte postado nele e a CPU chegou a 380% | https://sergioprado.org/desafio-do-mes-programacao-paralela-com-o-openmp/ |



7. Re: CPU

Fernando
phoemur

(usa Debian)

Enviado em 30/01/2018 - 20:46h

iostream é do C++, stdio.h é do C puro
Meu código é C++

Para compilar é com
g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread

assumindo que seu arquivo é o mersenne.cpp
Ou seja, GCC é para linguagem C, G++ é para C++, (mas também é gcc).


8. Re: CPU

Antonio Donato Filho
Donato100

(usa Ubuntu)

Enviado em 30/01/2018 - 21:31h

Ainda deu um erro:
mersenne.cpp:6:40: fatal error: boost/multiprecision/gmp.hpp: Arquivo ou diretório não encontrado
compilation terminated.

Usei a linhga de comando g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread
Salvei seu script como mersenne.cpp.




9. Re: CPU

Fernando
phoemur

(usa Debian)

Enviado em 02/02/2018 - 19:14h

Donato100 escreveu:

Ainda deu um erro:
mersenne.cpp:6:40: fatal error: boost/multiprecision/gmp.hpp: Arquivo ou diretório não encontrado
compilation terminated.

Usei a linhga de comando g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread
Salvei seu script como mersenne.cpp.



sudo apt-get install libboost-all-dev 



10. CPU [Resolvido]

Antonio Donato Filho
Donato100

(usa Ubuntu)

Enviado em 05/02/2018 - 12:18h

Desculpe o boost não estava instalado,compiloue executou.

//**3//****//

7**//

//**31**//

//**127**//

//**8191**//

//**131071**//

//**524287**//
Seria possivel imprimir somente os expoentes?
M2 M3 M5 M7 M13 M 17 M19.............
Os numeros ficam muito grandes depois de tempo.
CPU 380% +-






11. Re: CPU

Fernando
phoemur

(usa Debian)

Enviado em 05/02/2018 - 22:14h

Mas daí é mais fácil ainda.
Agora veja que se você quiser uma melhor performance você vai ter que melhorar o algoritmo, pois o algoritmo simples desse meu programa é mais lento. É mais pra exemplificar.

Veja os comentários das otimizações que aquele código em C que você colocou executa e por isso é mais rápido:

/* if p is composite, 2^p-1 is not prime */
/* trust the PRP test for these values */
/* If p=3 mod 4 and p,2p+1 both prime, then 2p+1 | 2^p-1. Cheap test. */
/* Do a little trial division first. Saves quite a bit of time. */ /* factor must be 1 or 7 mod 8 and a prime */
/* mpz_mod(V, V, mp) but more efficiently done given mod 2^p-1 */
/* while (n > mp) { n = (n >> p) + (n & mp) } if (n==mp) n=0 */
/* but in this case we can have at most one loop plus a carry */


Dito isso segue o código:

// g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread
#include <iostream>
#include <vector>
#include <future>
#include <boost/multiprecision/gmp.hpp>

using namespace boost::multiprecision;

// returns 2^exp - 1
mpz_int power(const uint64_t exp)
{
mpz_int number = 2;
for (uint64_t i = 1; i < exp; ++i) {
number *= 2;
}

number--;

return number;
}

// Performs LL test for exp if exp is odd
bool lucas_lehmer(uint64_t exp)
{
uint64_t res = exp;

// corner cases
if (exp == 2) {
std::cout << "M" << res << " " << std::flush;
return true;
}
else if (exp%2 == 0) return false;

// main calc
mpz_int s = 4;
mpz_int number = power(exp);

while (exp > 2) {
s = (s*s - 2) % number;
exp--;
}

if (s == 0) {
std::cout << "M" << res << " " << std::flush;
return true;
}
else return false;
}

auto async_worker(const uint64_t n)
{
std::vector<std::future<bool>> fut;
fut.reserve(n);

for (uint64_t i = 1; i<=n; ++i) {
fut.push_back(std::async(lucas_lehmer, i));
}

return fut;
}


int main(int argc, char* argv[])
{
uint64_t n = 43112609;
if (argc > 1) n = std::stoul(argv[1]);

auto vec = async_worker(n);

for (auto& i: vec) {
i.get();
}


return 0;
}




12. Re: CPU

Antonio Donato Filho
Donato100

(usa Ubuntu)

Enviado em 06/02/2018 - 08:38h

phoemur escreveu:

Mas daí é mais fácil ainda.
Agora veja que se você quiser uma melhor performance você vai ter que melhorar o algoritmo, pois o algoritmo simples desse meu programa é mais lento. É mais pra exemplificar.

Veja os comentários das otimizações que aquele código em C que você colocou executa e por isso é mais rápido:

/* if p is composite, 2^p-1 is not prime */
/* trust the PRP test for these values */
/* If p=3 mod 4 and p,2p+1 both prime, then 2p+1 | 2^p-1. Cheap test. */
/* Do a little trial division first. Saves quite a bit of time. */ /* factor must be 1 or 7 mod 8 and a prime */
/* mpz_mod(V, V, mp) but more efficiently done given mod 2^p-1 */
/* while (n > mp) { n = (n >> p) + (n & mp) } if (n==mp) n=0 */
/* but in this case we can have at most one loop plus a carry */


Dito isso segue o código:

// g++ -O3 -Wall -o mersenne mersenne.cpp --std=c++14 -lgmp -lpthread
#include <iostream>
#include <vector>
#include <future>
#include <boost/multiprecision/gmp.hpp>

using namespace boost::multiprecision;

// returns 2^exp - 1
mpz_int power(const uint64_t exp)
{
mpz_int number = 2;
for (uint64_t i = 1; i < exp; ++i) {
number *= 2;
}

number--;

return number;
}

// Performs LL test for exp if exp is odd
bool lucas_lehmer(uint64_t exp)
{
uint64_t res = exp;

// corner cases
if (exp == 2) {
std::cout << "M" << res << " " << std::flush;
return true;
}
else if (exp%2 == 0) return false;

// main calc
mpz_int s = 4;
mpz_int number = power(exp);

while (exp > 2) {
s = (s*s - 2) % number;
exp--;
}

if (s == 0) {
std::cout << "M" << res << " " << std::flush;
return true;
}
else return false;
}

auto async_worker(const uint64_t n)
{
std::vector<std::future<bool>> fut;
fut.reserve(n);

for (uint64_t i = 1; i<=n; ++i) {
fut.push_back(std::async(lucas_lehmer, i));
}

return fut;
}


int main(int argc, char* argv[])
{
uint64_t n = 43112609;
if (argc > 1) n = std::stoul(argv[1]);

auto vec = async_worker(n);

for (auto& i: vec) {
i.get();
}


return 0;
}


Ficou otímo,agradeço
antonio@donato:~/Área de Trabalho/teste$ ./mersenne
MM23 M5 M7 M13 M17 M19 M31 M61 M89 M107 M127 M521 M607 M1279 M2203 M2281 M3217 M4253








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts