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**//