PrimeGrid challenge strategy thread (Comments? Suggestions? This *is* a democracy!)

Page 2 - Seeking answers? Join the AnandTech community: where nearly half-a-million members share solutions and discuss the latest tech.

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,208
3,768
75
Ken_g6, do you have a bash script that would start PrimeGrid at the right time for the challenge?

And perhaps, another one to force an upload at the deadline?

I think I can do one that does both! :) I started it before the challenge, but didn't post it because things like this never work without testing. And it did need testing - I almost aborted a bunch of WUs, and I did suspend work for about 4 minutes. :$

But I think it's working now, so here it is for the next race:

Code:
#!/bin/bash
# Wait until the next PrimeGrid race, then kick off BOINC on that race.

thisyear=`date +%Y`

function parsedate {
	timestr=`date -u --date "$1" +%s`
	echo $timestr
}

# Sleep until the given time, minus the offset in seconds.
function sleepuntil {
	timestr="$1"
	offset="$2"

	localnow=`date -u +%s`
	# Get the current time from the PrimeGrid main page.
	pgnow=`wget -q -Yoff -O- -T 10 http://www.primegrid.com/ | grep "serverstatus italic" | grep "$thisyear-" | sed -e "s/^[^>]*>//;s/<.*$//"`
	pgnow=`date -u --date "$pgnow" +%s`
	if [ "$pgnow" == "" ] ; then
		echo Warning: PrimeGrid server inaccessible - using local date.
		pgnow="$localnow"
	fi
	let "sleeptime = $timestr-$pgnow-$offset"

	if [ "$sleeptime" -gt "0" ] ; then
		echo Sleeping $sleeptime seconds, until about $offset seconds before the race time.
		sleep $sleeptime
		return 0
	else
		echo Time already passed by $sleeptime seconds!
		return 1
	fi
}

# Parse out the race date, not from the timer.
racedate=`wget -q -Yoff -O- -T 10 http://www.primegrid.com/ | grep ' \((UTC)\|UTC &ndash; \)'`

if [ "$racedate" == "" ] ; then 
	echo "No PrimeGrid race found."
	exit
fi

enddate=`echo "$racedate" | sed -e 's/^.*\( UTC &ndash; \| to \)//;s/(\?UTC.*$/UTC/' | sed -e "s/ \([0-9]\+:\)/ $thisyear \1/"`
racedate=`echo "$racedate" | sed -e 's/\( to .*\)\?UTC.*$/ UTC/;s/^.*>//' | sed -e "s/ \([0-9]\+:\)/ $thisyear \1/"`
#racedate=`wget -q -Yoff -O- -T 10 http://www.primegrid.com/ | grep "MissionTimer(" | sed -e 's/^[^"]*"//;s/".*$//'`
racedate=`parsedate "$racedate"`
if [ "$enddate" != "" ] ; then
	echo Race will end $enddate
	enddate=`parsedate "$enddate"`
fi

if sleepuntil "$racedate" 300 ; then 
	boinccmd --project http://www.primegrid.com/ suspend

	# Find all incomplete PrimeGrid tasks and abort them.
	for i in `boinccmd --get_tasks | grep "^   \(project URL\|state\|name\): " | grep -A 1 -B 1 "http://www.primegrid.com" | grep -B 2 "^   state: [^5]" | grep "^   name: " | sed -e "s/^   name: //"` ; do
		boinccmd --task http://www.primegrid.com/ $i abort
	done
fi
toflush=`boinccmd --get_tasks | grep "^   \(project URL\|state\): " | grep -A 1 "http://www.primegrid.com" | grep "^   state: 5" | wc -l`
if [ "$toflush" != "0" ] ; then
	boinccmd --project http://www.primegrid.com/ update
fi

if sleepuntil "$racedate" 0 ; then
	# Suspend all projects.
	for i in `boinccmd --get_project_status | grep "^   master URL: " | sed -e "s/^   master URL: //"` ; do
		boinccmd --project $i suspend
	done

	# Start PrimeGrid.
	boinccmd --project http://www.primegrid.com/ resume
        boinccmd --project http://www.primegrid.com/ allowmorework
	boinccmd --project http://www.primegrid.com/ update
else
	echo Race already started!
fi

# For the next up-to-30 days, flush before the race start time.
if [ "$enddate" != "" ] ; then racedate="$enddate"
else let "racedate = $racedate + 86400"
fi
for I in `seq 1 30` ; do
	sleepuntil "$racedate" 3600
	istimer=`wget -q -Yoff -O- -T 10 http://www.primegrid.com/ | grep "MissionTimer(" | wc -l`
	if [ "$istimer" == "0" ] ; then break ; fi
	for j in 1800 900 450 225 100 10 1 0 0 ; do
		toflush=`boinccmd --get_tasks | grep "^   \(project URL\|state\): " | grep -A 1 "http://www.primegrid.com" | grep "^   state: 5" | wc -l`
		if [ "$toflush" != "0" ] ; then
			boinccmd --project http://www.primegrid.com/ update
			echo Flushing $toflush tasks!
		fi
		sleepuntil "$racedate" $j
	done
	if [ "$enddate" != "" ] ; then break; fi
	sleep 3600
	istimer=`wget -q -Yoff -O- -T 10 http://www.primegrid.com/ | grep "MissionTimer(" | wc -l`
	if [ "$istimer" == "0" ] ; then break ; fi
	let "racedate = $racedate + 86400"
done

echo "Race over!"

# Resume all projects.
#for I in `boinccmd --get_project_status | grep "^   master URL: " | sed -e "s/^   master URL: //"` ; do
	#boinccmd --project $I resume
#done

Uncomment that last section if you want to let BOINC do something else when the race ends.

Edit 6/8/10: Fixed for recent timer changes: they now do a countdown to the end.
Edit 12/15/12: Changed all references to "result" to "task". Change them back for pre-6.12 BOINC clients, or upgrade.
Edit 3/10/13: I think this fixes when allowmorework should be called.
 
Last edited:

Rudy Toody

Diamond Member
Sep 30, 2006
4,267
421
126
Thanks, Ken!

I will play around with it to make sure it works on my rigs and will use it the next time I do one of these challenges.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,208
3,768
75
The June project has been updated: It will be TRP Sieve - basically, Riesel Sieve. :)
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,208
3,768
75
Ken's work unit juggling guide for multi-core CPUs, from the 2010 Calendula Challenge, last updated October 2011:
smilie_character_juggle.gif


The easiest way to juggle work in is actually to add N-1 WUs on N cores. It's less like juggling than it is like a game of dominoes.
  1. Take your first N WUs to N-1/N*100 percent.
  2. Ensure you have downloaded N-1 more WUs and that your existing work is not running at "high priority" afterwards.
  3. Suspend N-1 WUs at N-1/N*100 percent. Let the new WUs start from 0%. Then resume the suspended WUs (leaving them in a ready-to-run state) and let everything finish.

For instance, to get 7 done on a quad-core:
  1. 75%, 75%, 75%, 75% - Take 4 to 3/4*100 = 75%.
  2. 75%, 75%, 75%, 75%, 0%, 0%, 0% - 3 more WUs downloaded, and the other WUs are not running at "high priority".
  3. 75%, 75%, 75%, 75%, 0%, 0%, 0% - Suspend 3 WUs, others start. Resume them and they go to a ready-to-run state. Note that you need do nothing more at this point, but I'll show what happens anyway.
  4. 100%, 75%, 75%, 75%, 25%, 25%, 25% - When 1 of the 75% WUs finishes, the next one starts automatically.
  5. 100%, 100%, 75%, 75%, 50%, 50%, 50% - When another of the 75% WUs finishes, the next one starts automatically.
  6. 100%, 100%, 100%, 75%, 75%, 75%, 75% - When the fourth one starts, the other 3 WUs are in sync with it.
  7. 100%, 100%, 100%, 100%, 100%, 100%, 100% - All done!

Now suppose you want to get N-M more WUs done, where N is the number of cores, and M is divisible by the number of cores. Well, simply treat M cores like one core. For example, on a hex-core system where you want to get 4 more WUs done, suspend all but 2 at M/N*100 = 4/6*100 = 66.7%. This should start 4 fresh WUs, and the others will finish in pairs.

To get 50% more work done on a dual-core (or multiply by the even number of cores you have over 2), follow the same rules.

It's less than 50% more work where you really have to juggle. To get N+1 WUs done on N cores, you can leave one of each of N+1 WUs idle in turn as you do 1/Nth of the work on the rest. An example with 4 cores, where green means they were running. (Sorry, I'll clean up the notation later.):
  1. 0%, 25%, 25%, 25%, 25% (1st WU idle.)
  2. 25%, 25%, 50%, 50%, 50% (2nd WU idle.)
  3. 50%, 50%, 50%, 75%, 75% (3rd WU idle.)
  4. 75%, 75%, 75%, 75%, 100% (4th WU idle.)
  5. 100%, 100%, 100%, 100%, 100% (5th WU idle, because it's done.)

If all this boggles your mind, don't worry about it. But I wanted to post it as a guide, in case it un-boggles some peoples' minds. :whiste:

Note: For almost all PrimeGrid LLR work, WU length increases as a challenge progresses. So you may want to either account for this or fetch all your work that you plan to juggle at the same time.
 
Last edited:

Rudy Toody

Diamond Member
Sep 30, 2006
4,267
421
126
it looks like a Monte Carlo betting system!

You won't get more work done, however you will have the work units at the last stage completed together.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,208
3,768
75
it looks like a Monte Carlo betting system!

You won't get more work done, however you will have the work units at the last stage completed together.
You won't get more work done overall, but you might get a few more work units in before the end of the race. I'm trying to get an extra one in this way right now. :)
 

Rudy Toody

Diamond Member
Sep 30, 2006
4,267
421
126
You won't get more work done overall, but you might get a few more work units in before the end of the race. I'm trying to get an extra one in this way right now. :)

Yes, it's a way to align the finish time to mod 2xWUtime, or 4x... or 6x... If every WU had a fixed time then you could do this at the start of the race, so everything finishes together.