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

cvsimport

parents 881edf4e 16cc7e39
......@@ -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);
}
}
; The Computer Language Benchmarks Game
; $Id: u64q.ini,v 1.361 2017/08/01 20:47:08 igouy-guest Exp $
; $Id: u64q.ini,v 1.362 2017/08/31 19:36:49 igouy-guest Exp $
;;; SECTIONS
......@@ -160,7 +160,7 @@ PYTHON3 = /usr/local/src/Python-3.6.1/bin/python3.6
RACKET = /usr/local/src/racket-6.10/bin/racket
RACO = /usr/local/src/racket-6.10/bin/raco
JRUBY = /usr/local/src/jruby-9.1.7.0/bin/jruby
RUST = /usr/local/src/rust-1.19.0/bin/rustc
RUST = /usr/local/src/rust-1.20.0/bin/rustc
SBCL = /usr/local/bin/sbcl
SCALA = /usr/local/src/scala-2.12.1
SCALAC = /usr/local/src/scala-2.12.1/bin/scalac
......
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