Commit bbd61daa authored by igouy-guest's avatar igouy-guest

*** empty log message ***


SKIPPED:
	website/websites/u64q/code/fannkuchredux.5.csharpcore.code
	website/websites/u64q/code/fannkuchredux.5.csharpcore.log
	website/websites/u64q/data/data.csv
	website/websites/u64q/data/ndata.csv
	website/websites/u64q/data/u64q_bulkdata.csv.bz2
parent 09267239
......@@ -3,22 +3,21 @@
contributed by Isaac Gouy, transliterated from Oleg Mazurov's Java program
concurrency fix and minor improvements by Peperud
TPL parallel and optimisations by Anthony Lloyd
parallel and small optimisations by Anthony Lloyd
*/
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
public static class FannkuchRedux
{
const long flipMask = uint.MaxValue, oneChk = flipMask+1, chkMask = oneChk * int.MaxValue;
static int[] fact, chkSums, maxFlips;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void firstPermutation(int n, int[] fact, int[] p, int[] pp, int[] count, int idx)
static void firstPermutation(int[] p, int[] pp, int[] count, int idx)
{
for (int i=0; i<n; ++i) p[i] = i;
for (int i=n-1; i>0; --i)
for (int i=0; i<p.Length; ++i) p[i] = i;
for (int i=count.Length-1; i>0; --i)
{
int d = idx/fact[i];
count[i] = d;
......@@ -51,67 +50,70 @@ public static class FannkuchRedux
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static long reduce(long l1, long l2)
static int countFlips(int first, int[] p, int[] pp)
{
return Math.Max(l1 & flipMask, l2 & flipMask) | ((l1+l2) & chkMask);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static long countFlips(int n, int[] p, int[] pp, int first, long sign, long chksumMaxflips)
{
if (first==0) return chksumMaxflips;
if (p[first]==0) return chksumMaxflips+sign;
for(int i=0; i<n; i++) pp[i] = p[i];
if (first==0) return 0;
if (p[first]==0) return 1;
for(int i=0; i<pp.Length; i++) pp[i] = p[i];
int flips = 2;
while(true)
{
for (int lo=1, hi=first-1; lo<hi; lo++,hi--)
for (int lo=1,hi=first-1; lo<hi; lo++,hi--)
{
int t = pp[lo];
pp[lo] = pp[hi];
pp[hi] = t;
}
int tp = pp[first];
if (pp[tp]==0) return Math.Max(chksumMaxflips & flipMask, flips) | (sign * flips + chksumMaxflips & chkMask);
if (pp[tp]==0) return flips;
pp[first] = first;
first = tp;
flips++;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static long run(int n, int[] fact, int taskId, int taskSize, long chksumMaxflips)
static void run(int n, int taskId, int taskSize)
{
int[] p = new int[n], pp = new int[n], count = new int[n];
firstPermutation(n, fact, p, pp, count, taskId*taskSize);
chksumMaxflips = countFlips(n, p, pp, p[0], oneChk, chksumMaxflips);
firstPermutation(p, pp, count, taskId*taskSize);
int chksum = countFlips(p[0], p, pp);
int maxflips = chksum;
while (--taskSize>0)
{
chksumMaxflips = countFlips(n, p, pp, nextPermutation(p, count), oneChk-oneChk*2*(taskSize%2), chksumMaxflips);
var flips = countFlips(nextPermutation(p, count), p, pp);
chksum += (1-(taskSize%2)*2) * flips;
if(flips>maxflips) maxflips = flips;
}
return chksumMaxflips;
chkSums[taskId] = chksum;
maxFlips[taskId] = maxflips;
}
public static void Main(string[] args)
{
int n = args.Length > 0 ? int.Parse(args[0]) : 7;
var fact = new int[n+1];
fact = new int[n+1];
fact[0] = 1;
var factn = 1;
for (int i=1; i<fact.Length; i++) { fact[i] = factn *= i; }
int nTasks = 2*3*4;
int nTasks = Environment.ProcessorCount;
chkSums = new int[nTasks];
maxFlips = new int[nTasks];
int taskSize = factn/nTasks;
long chksumMaxflips = 1;
Parallel.For<long>(0, nTasks
, () => 1
, (i,_,l) => run(n, fact, i, taskSize, l)
, l => {
long chk;
do { chk = chksumMaxflips; }
while (Interlocked.CompareExchange(ref chksumMaxflips, reduce(chk, l), chk) != chk);
}
);
Console.Out.WriteLineAsync(((chksumMaxflips & chkMask) / oneChk) + "\nPfannkuchen("+n+") = " + (chksumMaxflips & flipMask));
var threads = new Thread[nTasks];
for(int i=1; i<nTasks; i++)
{
int j = i;
(threads[j] = new Thread(() => run(n, j, taskSize))).Start();
}
run(n, 0, taskSize);
int chksum=chkSums[0], maxflips=maxFlips[0];
for(int i=1; i<threads.Length; i++)
{
threads[i].Join();
chksum += chkSums[i];
if(maxFlips[i]>maxflips) maxflips = maxFlips[i];
}
Console.Out.WriteLineAsync(chksum+"\nPfannkuchen("+n+") = "+maxflips);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment