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.
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
Donato100usa Ubuntu
Post recolhido
Enviado em 30/01/2018 - 18:19h
Como seria?
Lembrando que sou leigo em C.
4. Re: CPU
Hgfsusa Arch Linux
Post recolhido
Enviado em 30/01/2018 - 19:20h
OpenMP é bem simples de implementar. Dá uma procurada aí.
5. Re: CPU
phoemurusa Debian
Post recolhido
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:
// 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...
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
phoemurusa Debian
Post recolhido
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
Donato100usa Ubuntu
Post recolhido
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
phoemurusa Debian
Post recolhido
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]
Donato100usa Ubuntu
Post recolhido
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
phoemurusa Debian
Post recolhido
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 */
// 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
Donato100usa Ubuntu
Post recolhido
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 */