Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 3d1f1f2c authored by Andreas Enge's avatar Andreas Enge
Browse files

Compute the Tonelli-Shanks generator once and for all.

This provides a speed-up when several rounds are needed in the main loop
for determining a CM discriminant, and in the MPI version it lets the
clients idle more.

* lib/cm-impl.h (cm_mpi_broadcast_N): Add parameters e, r and z to
  prototype.
* lib/ecpp.c (compute_qroot): Add e, r and z as parameters to the non-MPI
  version and do not compute them.
  (find_ecpp_discriminant): Compute e, r and z and adapt function calls.
* lib/mpi.c (cm_mpi_broadcast_N): Broadcast e, r and z.
  (mpi_worker): Receive e, r and z.
parent 2f875109
No related branches found
No related tags found
No related merge requests found
...@@ -280,7 +280,8 @@ extern void cm_mpi_queue_push (int rank); ...@@ -280,7 +280,8 @@ extern void cm_mpi_queue_push (int rank);
extern int cm_mpi_queue_pop (void); extern int cm_mpi_queue_pop (void);
extern unsigned long int cm_mpi_compute_B (void); extern unsigned long int cm_mpi_compute_B (void);
extern void cm_mpi_broadcast_init (bool verbose, bool debug); extern void cm_mpi_broadcast_init (bool verbose, bool debug);
extern void cm_mpi_broadcast_N (mpz_srcptr N); extern void cm_mpi_broadcast_N (mpz_srcptr N, unsigned int e,
mpz_srcptr r, mpz_srcptr z);
extern void cm_mpi_broadcast_sqrt (int no_qstar, long int *qstar, extern void cm_mpi_broadcast_sqrt (int no_qstar, long int *qstar,
mpz_t *qroot); mpz_t *qroot);
extern void cm_mpi_clear_N (void); extern void cm_mpi_clear_N (void);
......
...@@ -41,7 +41,7 @@ static double expected_no_curves (long int *qstar, int no_qstar_old, ...@@ -41,7 +41,7 @@ static double expected_no_curves (long int *qstar, int no_qstar_old,
uint_cl_t hmaxprime, unsigned int *h); uint_cl_t hmaxprime, unsigned int *h);
static void compute_qroot (mpz_t *qroot, long int *qstar, int no_qstar, static void compute_qroot (mpz_t *qroot, long int *qstar, int no_qstar,
#ifndef WITH_MPI #ifndef WITH_MPI
mpz_srcptr p, mpz_srcptr p, unsigned int e, mpz_srcptr r, mpz_srcptr z,
#endif #endif
cm_stat_t stat); cm_stat_t stat);
static void sqrt_d (mpz_ptr Droot, int_cl_t d, mpz_srcptr N, static void sqrt_d (mpz_ptr Droot, int_cl_t d, mpz_srcptr N,
...@@ -598,16 +598,16 @@ static double expected_no_curves (long int *qstar, int no_qstar_old, ...@@ -598,16 +598,16 @@ static double expected_no_curves (long int *qstar, int no_qstar_old,
static void compute_qroot (mpz_t *qroot, long int *qstar, int no_qstar, static void compute_qroot (mpz_t *qroot, long int *qstar, int no_qstar,
#ifndef WITH_MPI #ifndef WITH_MPI
mpz_srcptr p, mpz_srcptr p, unsigned int e, mpz_srcptr r, mpz_srcptr z,
#endif #endif
cm_stat_t stat) cm_stat_t stat)
/* Compute in qroot the square roots of the no_qstar elements of qstar /* Compute in qroot the square roots of the no_qstar elements of qstar
(assumed to be squares) modulo p. qroot needs to be initialised to (assumed to be squares) modulo p. qroot needs to be initialised to
the correct size, and its entries need to be initialised as well. */ the correct size, and its entries need to be initialised as well.
e, r and z are the return value and the values q and z computed by
cm_nt_tonelli_generator. */
{ {
#ifndef WITH_MPI #ifndef WITH_MPI
unsigned int e;
mpz_t r, z;
int i; int i;
#else #else
MPI_Status status; MPI_Status status;
...@@ -617,14 +617,9 @@ static void compute_qroot (mpz_t *qroot, long int *qstar, int no_qstar, ...@@ -617,14 +617,9 @@ static void compute_qroot (mpz_t *qroot, long int *qstar, int no_qstar,
#ifndef WITH_MPI #ifndef WITH_MPI
cm_timer_continue (stat->timer [0]); cm_timer_continue (stat->timer [0]);
mpz_init (r);
mpz_init (z);
e = cm_nt_mpz_tonelli_generator (r, z, p);
for (i = 0; i < no_qstar; i++) for (i = 0; i < no_qstar; i++)
cm_nt_mpz_tonelli_si_with_generator (qroot [i], qstar [i], cm_nt_mpz_tonelli_si_with_generator (qroot [i], qstar [i],
p, e, r, z); p, e, r, z);
mpz_clear (r);
mpz_clear (z);
cm_timer_stop (stat->timer [0]); cm_timer_stop (stat->timer [0]);
#else #else
sent = 0; sent = 0;
...@@ -1052,6 +1047,8 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N, ...@@ -1052,6 +1047,8 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N,
double exp_prime, min_prime; double exp_prime, min_prime;
int round, i; int round, i;
cm_timer_t timer; cm_timer_t timer;
unsigned int e;
mpz_t r, z;
#ifdef WITH_MPI #ifdef WITH_MPI
MPI_Status status; MPI_Status status;
int size, rank, job; int size, rank, job;
...@@ -1069,9 +1066,20 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N, ...@@ -1069,9 +1066,20 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N,
qstar = (long int *) malloc (0); qstar = (long int *) malloc (0);
root = (mpz_t *) malloc (0); root = (mpz_t *) malloc (0);
mpz_init (r);
mpz_init (z);
cm_timer_start (timer);
e = cm_nt_mpz_tonelli_generator (r, z, N);
cm_timer_stop (timer);
if (debug) {
printf (" Tonelli generator: (%4.0f)\n",
cm_timer_wc_get (timer));
fflush (stdout);
}
#ifdef WITH_MPI #ifdef WITH_MPI
MPI_Comm_size (MPI_COMM_WORLD, &size); MPI_Comm_size (MPI_COMM_WORLD, &size);
cm_mpi_broadcast_N (N); cm_mpi_broadcast_N (N, e, r, z);
no_qstar_delta = size - 1; no_qstar_delta = size - 1;
#else #else
no_qstar_delta = 1; no_qstar_delta = 1;
...@@ -1125,7 +1133,7 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N, ...@@ -1125,7 +1133,7 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N,
compute_qroot (root + no_qstar_old, qstar + no_qstar_old, compute_qroot (root + no_qstar_old, qstar + no_qstar_old,
no_qstar_new, no_qstar_new,
#ifndef WITH_MPI #ifndef WITH_MPI
N, N, e, r, z,
#endif #endif
stat); stat);
#ifdef WITH_MPI #ifdef WITH_MPI
...@@ -1252,6 +1260,8 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N, ...@@ -1252,6 +1260,8 @@ static int_cl_t find_ecpp_discriminant (mpz_ptr n, mpz_ptr l, mpz_srcptr N,
mpz_clear (root [i]); mpz_clear (root [i]);
free (root); free (root);
free (qstar); free (qstar);
mpz_clear (r);
mpz_clear (z);
if (debug) { if (debug) {
printf (" size gain: %lu bits\n", printf (" size gain: %lu bits\n",
......
...@@ -260,7 +260,8 @@ void cm_mpi_broadcast_init (bool verbose, bool debug) ...@@ -260,7 +260,8 @@ void cm_mpi_broadcast_init (bool verbose, bool debug)
/*****************************************************************************/ /*****************************************************************************/
void cm_mpi_broadcast_N (mpz_srcptr N) void cm_mpi_broadcast_N (mpz_srcptr N, unsigned int e,
mpz_srcptr r, mpz_srcptr z)
/* Send data depending on N to all workers. */ /* Send data depending on N to all workers. */
{ {
int size, rank; int size, rank;
...@@ -270,6 +271,11 @@ void cm_mpi_broadcast_N (mpz_srcptr N) ...@@ -270,6 +271,11 @@ void cm_mpi_broadcast_N (mpz_srcptr N)
MPI_Send (&rank, 1, MPI_INT, rank, MPI_TAG_JOB_BROADCAST_N, MPI_Send (&rank, 1, MPI_INT, rank, MPI_TAG_JOB_BROADCAST_N,
MPI_COMM_WORLD); MPI_COMM_WORLD);
mpi_bcast_send_mpz (N, MPI_COMM_WORLD); mpi_bcast_send_mpz (N, MPI_COMM_WORLD);
MPI_Bcast (&e, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD);
if (e > 1) {
mpi_bcast_send_mpz (r, MPI_COMM_WORLD);
mpi_bcast_send_mpz (z, MPI_COMM_WORLD);
}
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -672,7 +678,11 @@ static void mpi_worker () ...@@ -672,7 +678,11 @@ static void mpi_worker ()
break; break;
case MPI_TAG_JOB_BROADCAST_N: case MPI_TAG_JOB_BROADCAST_N:
mpi_bcast_recv_mpz (N, MPI_COMM_WORLD); mpi_bcast_recv_mpz (N, MPI_COMM_WORLD);
e = cm_nt_mpz_tonelli_generator (r, z, N); MPI_Bcast (&e, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD);
if (e > 1) {
mpi_bcast_recv_mpz (r, MPI_COMM_WORLD);
mpi_bcast_recv_mpz (z, MPI_COMM_WORLD);
}
break; break;
case MPI_TAG_JOB_BROADCAST_SQRT: case MPI_TAG_JOB_BROADCAST_SQRT:
MPI_Bcast (&no_qstar_new, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&no_qstar_new, 1, MPI_INT, 0, MPI_COMM_WORLD);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment