Beispiel #1
0
        protected override void CoreRunKernel(IGrid grid, IKernel kernel)
        {
            // todo. so far we have just this totally uninformative flag
            // 1) this solution is better than receiving AppDomain.UnhandledException
            //    since this way we ensure that we track only threads that we create
            // 2) further implementations might include exception unwrapping and multiplexing
            //    just like TPL/PLINQ does: (soz, can't find the link about AggregatedException)
            var crashCount = 0;

            var gridDims  = new [] { grid.GridDim.Z, grid.GridDim.Y, grid.GridDim.X };
            var numBlocks = gridDims.Product();
            var workers   = 0.UpTo(Config.Cores - 1).Select(i => new Thread(() =>
            {
                var chunkSize = (int)Math.Ceiling(numBlocks * 1.0 / Config.Cores);
                var start     = i * chunkSize;
                var end       = Math.Min((i + 1) * chunkSize, (int)numBlocks) - 1;

                start.UpTo(end).ForEach(j =>
                {
                    var dimSizes = gridDims.Scanrae(1, (curr, dim, _) => curr * dim).ToReadOnly();
                    var indices  = dimSizes.SkipLast(1).Scanrbi(j, (curr, dimSize, _) => curr % dimSize, (curr, dimSize, _) => curr / dimSize, (curr, _) => curr).ToReadOnly();
                    var blid     = new int3(indices[2], indices[1], indices[0]);

                    try
                    {
                        var blockRunner = kernel.AssertCast <IBlockRunner>();
                        blockRunner.RunBlock(blid);
                    }
                    catch (Exception ex)
                    {
                        Interlocked.Increment(ref crashCount);
                        throw new KernelThreadException(kernel, GridDim, blid, BlockDim, null, Thread.CurrentThread.Name, ex);
                    }
                });
                // todo. also mess with thread affinities to ensure maximally possible CPU load
            })
            {
                Name = "Conflux CPU runtime worker thread #" + i
            }).ToReadOnly();

            workers.ForEach(w => w.Start());
            workers.ForEach(w => w.Join());
            (crashCount == 0).AssertTrue();
        }