![]() |
|
|
#12 |
|
Jun 2003
Oxford, UK
2·7·139 Posts |
|
|
|
|
|
|
#13 | |
|
Jun 2003
Oxford, UK
2×7×139 Posts |
Quote:
Using 1346 and 134 on my code reduces the time on my computer to 133 seconds. Clearly 1346 was chosen as it is the lowest prime gap which is not classified as first occurrence and 134 is 10% of that. I would suggest the optimal percentage might be a bit higher based on my 850 and 150 experience. |
|
|
|
|
|
|
#14 | |
|
Just call me Henry
"David"
Sep 2007
Cambridge (GMT/BST)
588610 Posts |
Quote:
Sieving large ranges gives the opportunity to cherry pick and attempt to create high merit gaps. |
|
|
|
|
|
|
#15 | |
|
"Dana Jacobsen"
Feb 2011
Bangkok, TH
22×227 Posts |
Quote:
Regardless I think we agree that light sieving is the better answer in the long run for finding maximal gaps (I still think it's the wrong thing for finding record gaps, which is a different problem). Since we know we're doing a big range so we can pre sieve a fairly large swath. Run in segments of size 323323 bytes for instance, and a memcpy at the start has already sieved the whole range up to 19. For the C code I posted, you could do the same in Perl for a little more overhead. I mostly wanted to get rid of the obvious "OMG, you're dong this in a horrifically slow language so it can never work" responses. The overhead does matter at some point, but for now we have more important (IMO) things like (1) is this correct, (2) is it substantially worse than a demonstrated other solution, (3) is it possible to make it faster and how, etc. |
|
|
|
|
|
|
#16 |
|
Jun 2003
Oxford, UK
2·7·139 Posts |
I am useless at perl threads, so I took one of danaj's working thread programs and stripped it back to essentials so that I could at least get a working code, see below.
I have set the bar rather low in terms of reporting results, as I am not confident that I am picking up all gaps over 700. I note that some results will appear more than once because of the fact that the $jumper is less than the target gap so it will jump into the same gap. I am also not confident at all that the code is efficient. With 7 threads it is not working anywhere near 7x as fast as the stand alone code I posted earlier. Using 800 and 700 as $mingap and $jumper It is working at about 2.12e12 an hour, so for a 50bn range that is maybe 84 seconds, compared to 190 seconds for the non-thread code (albeit that was only looking for gaps of 1000, but the threaded code is certainly nowhere near 7x). Maybe someone could have a look at it and see what I am doing wrong. Code:
#!/usr/bin/env perl
use warnings;
use strict;
use threads;
use threads::shared;
use Math::GMPz;
use Math::BigFloat lib=>"GMP";
use Math::Prime::Util qw/:all/;
$|=1;
my $nthreads = 7;
my $beg = shift || 4_000_000_000_000_000_000;
my $end = shift || 4_001_000_000_000_000_000;
my $jumper = 600;
my $mingap = 700;
my @results :shared;
my @threads;
push @threads, threads->create('searchi', $_,$jumper,$mingap) for 0 .. $nthreads-1;
$_->join() for (@threads);
while (@results) {
print shift(@results);
}
sub searchi {
my($tnum,$sn,$nth) = @_;
my $index = $tnum;
while (1) {
if ($tnum == 0 && @results) {
lock(@results);
while (@results) {
print shift(@results);
}
}
my $i = $beg+($index*$jumper);
$index += $nthreads;
last if $i > $end;
my $n = $i;
my $forwardlook = $mingap-$jumper;
my $dprev = prev_prime($n);
my $dnext = next_prime($n);
next unless $dnext>$n+$forwardlook;
my $gap = $dnext-$dprev;
next unless $gap >= $mingap;
{
lock(@results);
push @results, sprintf("%d %d\n", $gap, $dprev);
}
}
1;
}
Last fiddled with by robert44444uk on 2017-04-09 at 14:14 |
|
|
|
|
|
#17 | |
|
"Antonio Key"
Sep 2011
UK
32·59 Posts |
Quote:
I've used an attachment, the [CODE] wrapper doesn't seem to be working for me at the moment! |
|
|
|
|
|
|
#18 |
|
Jun 2003
Oxford, UK
2×7×139 Posts |
Thank you for posting Antonio. I'll check it for speed on my machine as soon as it gets free.
|
|
|
|
|
|
#19 |
|
"Antonio Key"
Sep 2011
UK
32·59 Posts |
Here is an alternative version which I estimate would take just over 6 days to cover a 1e15 range looking for gaps >= 1346, This is using 4 cores of my i5-3570k at 4.3GHz.
Each thread tests a portion of the complete range, so results may not be output in order of initiating prime. Code:
#!/usr/bin/env perl
#
use warnings;
use strict;
use threads;
use threads::shared;
use Math::Prime::Util qw/:all/;
$|=1;
my $instances = shift || 4;
$instances = $instances % 100;
my $ps = shift || 4_000_023_100_000_000_000;
my $pe = shift || 4_000_023_150_000_000_000;
$ps = sprintf("%d", $ps);
$pe = sprintf("%d", $pe);
my $target = shift || 1000;
my %pstart;
my %pend;
my @results :shared;
print "\n";
print "Requested Threads.................. = $instances\n";
print "Requested search start............. = $ps\n";
print "Requested search end............... = $pe\n";
print "Requested target gap............... = $target\n\n";
$target = $target - $target % 2; # ensure the gap is even
my $head = int(0.1 * $target);
$head = $head + 1 unless $head % 2; # ensure adder is odd
my $tail = $target - $head;
$ps = prev_prime($ps + 1);
my $step = int(($pe - $ps) / $instances);
$pe = next_prime($pe - 1);
$step = $step + 1 if ($ps + $instances * $step) < $pe;
my $p2e = $ps;
my $instance = 0;
while ($instance < $instances) {
my $p2 = $ps + $step * ($instance + 1);
my $p1s = $p2e;
$p2e = next_prime($p2 - 1);
$pstart{$instance} = $p1s;
$pend{$instance} = $p2e;
$instance++;
}
print "Starting prime to ensure full cover = $pstart{0}\n";
print "Ending prime to ensure full cover.. = $pend{$instances - 1}\n";
print "Searching for gaps................ >= $target\n";
print "Forward skip....................... = $tail\n";
print "Looking for forward gap........... >= $head\n";
print "\n";
my $start = time;
print "started search\n\n";
my @threads;
push @threads, threads->create('searchi', $_) for 0 .. $instances - 1;
$_ -> join() for (@threads);
while (@results) {
print shift(@results);
}
my $duration = time - $start;
print "Execution time: $duration s\n";
my $rate = int(($pe - $ps) / $duration + 0.5);
printf("Rate = %d/sec.\n", $rate);
exit;
sub searchi {
my $tnum = $_;
my $n = $pstart{$tnum};
my $pprime = $n;
my $nprime = $n;
my $pe = $pend{$tnum};
if ($tnum){
while ($n < $pe) {
$n = $nprime + $tail;
$nprime = Math::Prime::Util::next_prime( $n );
next unless ($nprime - $n) >= $head;
$pprime = Math::Prime::Util::prev_prime( $n );
next unless ($nprime - $pprime) >= $target;
my $gap = $nprime - $pprime;
{
lock(@results);
push @results, sprintf ("%8d %s\n", $gap, $pprime);
}
}
}else {
while ($n < $pe) {
if (@results) {
lock(@results);
while (@results) {
print shift(@results);
}
}
$n = $nprime + $tail;
$nprime = Math::Prime::Util::next_prime( $n );
next unless ($nprime - $n) >= $head;
$pprime = Math::Prime::Util::prev_prime( $n );
next unless ($nprime - $pprime) >= $target;
my $gap = $nprime - $pprime;
{
lock(@results);
push @results, sprintf ("%8d %s\n", $gap, $pprime);
}
}
}
1;
}
Last fiddled with by Antonio on 2017-04-12 at 19:48 Reason: Picked up wrong code initially |
|
|
|
|
|
#20 | |
|
Jun 2003
Oxford, UK
2·7·139 Posts |
Quote:
It would be useful if you could a programme in a soft exit controlled by a key which records in the output file the lowest integer not tested. Alternatively one which outputs the lowest integer not tested every hour say as the gap results are quite rare. But, thanks Antonio! You should post this code to http://www.mersenneforum.org/showthread.php?t=22187 Why don't you join in the hunt by choosing a range? Last fiddled with by robert44444uk on 2017-04-13 at 07:09 |
|
|
|
|
|
|
#21 | |
|
"Antonio Key"
Sep 2011
UK
32×59 Posts |
Quote:
As to posting the code, it is still experimental and I am still trying to fine tune and tidy it up, but I will post a version in the next couple of days, and I may join the hunt at the end of the month when I will have some time and resources available. |
|
|
|
|
|
|
#22 | |
|
Jun 2003
Oxford, UK
2·7·139 Posts |
Quote:
On the code, I think you will need to break up the range that is covered by each thread into smaller chunks given that 1e15 is a large number and there maybe times when program breaks are required. Perhaps each thread should work on say 5 minutes worth of work, given that the call back for new integer ranges does not eat into processing time. |
|
|
|
|
![]() |
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Need some help on php programming | pinhodecarlos | Programming | 2 | 2012-07-23 18:17 |
| New to programming. What to do? | lorgix | Miscellaneous Math | 9 | 2010-12-08 22:22 |
| plz, help me in c programming | alaa | Homework Help | 12 | 2007-06-12 22:17 |
| Powerful Numbers programming challenge | geoff | Programming | 31 | 2005-02-20 18:25 |
| programming challenge | Fusion_power | Puzzles | 25 | 2003-08-21 15:56 |