Skip to content
Snippets Groups Projects
Commit 421c63c4 authored by Tobias Pietzsch's avatar Tobias Pietzsch
Browse files

Revise CacheControl to be able to bundle and forward to multiple caches

CacheIoTiming was moved out of the CacheControl interface. I/O statistics
and time budget is now global per ThreadGroup and can be obtained through
static methods of CacheIoTiming.

The number of priority levels in the IoTimeBudget is not fixed anymore. It
adapts when a new budget is set. Querying and using budget clamp specified
level to the current number of priority levels.

# Conflicts:
#	src/main/java/bdv/cache/LoadingVolatileCache.java
#	src/main/java/bdv/img/cache/VolatileGlobalCellCache.java
parent c279d30c
Branches
No related tags found
No related merge requests found
Showing
with 275 additions and 349 deletions
......@@ -54,35 +54,10 @@ public interface CacheControl
*/
public void prepareNextFrame();
/**
* (Re-)initialize the IO time budget.
*/
public void initIoTimeBudget( final long[] partialBudget );
/**
* Get the {@link CacheIoTiming} that provides per thread-group IO
* statistics and budget.
*/
public CacheIoTiming getCacheIoTiming();
public static class Dummy implements CacheControl
{
private CacheIoTiming cacheIoTiming;
@Override
public void prepareNextFrame()
{}
@Override
public void initIoTimeBudget( final long[] partialBudget )
{}
@Override
public CacheIoTiming getCacheIoTiming()
{
if ( cacheIoTiming == null )
cacheIoTiming = new CacheIoTiming();
return cacheIoTiming;
}
}
}
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package bdv.cache;
import java.util.concurrent.ConcurrentHashMap;
import net.imglib2.ui.util.StopWatch;
/**
* Utilities for per {@link ThreadGroup} measuring and budgeting of time spent
* in (blocking) IO.
*
* @author Tobias Pietzsch <tobias.pietzsch@gmail.com>
*/
public class CacheIoTiming
{
/**
* Budget of time that can be spent in blocking IO. The budget is grouped by
* priority levels, where level 0 is the highest priority. The budget for
* level <em>i &gt; j</em> must always be smaller-equal the budget for level
* <em>j</em>.
*/
public static class IoTimeBudget
{
private final long[] budget;
public IoTimeBudget( final int numLevels )
{
budget = new long[ numLevels ];
}
public synchronized void reset( final long[] partialBudget )
{
if ( partialBudget == null )
clear();
else
{
for ( int i = 0; i < budget.length; ++i )
budget[ i ] = partialBudget.length > i ? partialBudget[ i ] : partialBudget[ partialBudget.length - 1 ];
for ( int i = 1; i < budget.length; ++i )
if ( budget[ i ] > budget[ i - 1 ] )
budget[ i ] = budget[ i - 1 ];
}
}
public synchronized void clear()
{
for ( int i = 0; i < budget.length; ++i )
budget[ i ] = 0;
}
public synchronized long timeLeft( final int level )
{
return budget[ level ];
}
public synchronized void use( final long t, final int level )
{
int l = 0;
for ( ; l <= level; ++l )
budget[ l ] -= t;
for ( ; l < budget.length && budget[ l ] > budget[ l - 1 ]; ++l )
budget[ l ] = budget[ l - 1 ];
}
}
public static class IoStatistics
{
private final ConcurrentHashMap< Thread, StopWatch > perThreadStopWatches = new ConcurrentHashMap<>();
private final StopWatch stopWatch;
private int numRunningThreads;
private long ioBytes;
private IoTimeBudget ioTimeBudget;
public IoStatistics()
{
stopWatch = new StopWatch();
ioBytes = 0;
numRunningThreads = 0;
ioTimeBudget = null;
}
public synchronized void start()
{
getThreadStopWatch().start();
if( numRunningThreads++ == 0 )
stopWatch.start();
}
public synchronized void stop()
{
getThreadStopWatch().stop();
if( --numRunningThreads == 0 )
stopWatch.stop();
}
public void incIoBytes( final long n )
{
ioBytes += n;
}
public long getIoBytes()
{
return ioBytes;
}
public long getIoNanoTime()
{
return stopWatch.nanoTime();
}
public long getCumulativeIoNanoTime()
{
long sum = 0;
for ( final StopWatch w : perThreadStopWatches.values() )
sum += w.nanoTime();
return sum;
}
public IoTimeBudget getIoTimeBudget()
{
return ioTimeBudget;
}
public void setIoTimeBudget( final IoTimeBudget budget )
{
ioTimeBudget = budget;
}
private StopWatch getThreadStopWatch()
{
final Thread thread = Thread.currentThread();
StopWatch w = perThreadStopWatches.get( thread );
if ( w == null )
{
w = new StopWatch();
perThreadStopWatches.put( thread, w );
}
return w;
}
}
private final ConcurrentHashMap< ThreadGroup, IoStatistics > perThreadGroupIoStatistics = new ConcurrentHashMap<>();
public IoStatistics getThreadGroupIoStatistics()
{
final ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
IoStatistics statistics = perThreadGroupIoStatistics.get( threadGroup );
if ( statistics == null )
{
statistics = new IoStatistics();
perThreadGroupIoStatistics.put( threadGroup, statistics );
}
return statistics;
}
}
......@@ -29,7 +29,7 @@
*/
package bdv.cache;
import bdv.cache.CacheIoTiming.IoTimeBudget;
import bdv.cache.iotiming.IoTimeBudget;
/**
* Describes how the cache processes requests for entries with missing data.
......
......@@ -29,8 +29,9 @@
*/
package bdv.cache;
import bdv.cache.CacheIoTiming.IoStatistics;
import bdv.cache.CacheIoTiming.IoTimeBudget;
import bdv.cache.iotiming.CacheIoTiming;
import bdv.cache.iotiming.IoStatistics;
import bdv.cache.iotiming.IoTimeBudget;
import bdv.cache.util.BlockingFetchQueues;
import bdv.cache.util.FetcherThreads;
import bdv.cache.util.Loader;
......@@ -65,22 +66,14 @@ import bdv.img.cache.VolatileGlobalCellCache;
*
* @author Tobias Pietzsch &lt;tobias.pietzsch@gmail.com&gt;
*/
public final class LoadingVolatileCache< K, V extends VolatileCacheValue > implements CacheControl
public final class LoadingVolatileCache< K, V extends VolatileCacheValue >
{
private final WeakSoftCache< K, Entry > cache = WeakSoftCache.newInstance();
private final WeakSoftCache< K, Entry > cache;
private final Object cacheLock = new Object();
private final CacheIoTiming cacheIoTiming = new CacheIoTiming();
private final int numPriorityLevels;
private final BlockingFetchQueues< Loader > queue;
private final FetcherThreads fetchers;
private volatile long currentQueueFrame = 0;
/**
* Create a new {@link LoadingVolatileCache} with the specified number of
* priority levels and number of {@link FetcherThreads} for asynchronous
......@@ -92,11 +85,18 @@ public final class LoadingVolatileCache< K, V extends VolatileCacheValue > imple
* the number of threads to create for asynchronous loading of
* cache entries.
*/
public LoadingVolatileCache( final int numPriorityLevels, final int numFetcherThreads )
// public LoadingVolatileCache( final int numPriorityLevels, final int numFetcherThreads )
// {
// queue = new BlockingFetchQueues<>( numPriorityLevels );
// fetchers = new FetcherThreads( queue, numFetcherThreads );
// }
public LoadingVolatileCache(
final WeakSoftCacheFactory cacheFactory,
final BlockingFetchQueues< Loader > queue )
{
this.numPriorityLevels = numPriorityLevels;
queue = new BlockingFetchQueues<>( numPriorityLevels );
fetchers = new FetcherThreads( queue, numFetcherThreads );
this.cache = cacheFactory.newInstance();
this.queue = queue;
}
/**
......@@ -194,68 +194,11 @@ public final class LoadingVolatileCache< K, V extends VolatileCacheValue > imple
}
/**
* Prepare the cache for providing data for the "next frame":
* <ul>
* <li>Move pending cell request to the prefetch queue (
* {@link BlockingFetchQueues#clearToPrefetch()}).
* <li>Perform pending cache maintenance operations (
* {@link WeakSoftCache#cleanUp()}).
* <li>Increment the internal frame counter, which will enable previously
* enqueued requests to be enqueued again for the new frame.
* </ul>
*/
@Override
public void prepareNextFrame()
{
queue.clearToPrefetch();
cache.cleanUp();
++currentQueueFrame;
}
/**
* (Re-)initialize the IO time budget, that is, the time that can be spent
* in blocking IO per frame/
*
* @param partialBudget
* Initial budget (in nanoseconds) for priority levels 0 through
* <em>n</em>. The budget for level <em>i &gt; j</em> must always
* be smaller-equal the budget for level <em>j</em>. If
* <em>n</em> is smaller than the number of priority levels, the
* remaining priority levels are filled up with @code{budget[n]}.
*/
@Override
public void initIoTimeBudget( final long[] partialBudget )
{
final IoStatistics stats = cacheIoTiming.getThreadGroupIoStatistics();
if ( stats.getIoTimeBudget() == null )
stats.setIoTimeBudget( new IoTimeBudget( numPriorityLevels ) );
stats.getIoTimeBudget().reset( partialBudget );
}
/**
* Get the {@link CacheIoTiming} that provides per thread-group IO
* statistics and budget.
*/
@Override
public CacheIoTiming getCacheIoTiming()
{
return cacheIoTiming;
}
/**
* Remove all references to loaded data as well as all enqueued requests
* from the cache.
* Remove all references to loaded data.
*/
public void invalidateAll()
{
queue.clear();
cache.invalidateAll();
prepareNextFrame();
}
public FetcherThreads getFetcherThreads()
{
return fetchers;
}
// ================ private methods =====================
......@@ -296,6 +239,7 @@ public final class LoadingVolatileCache< K, V extends VolatileCacheValue > imple
*/
private void enqueueEntry( final Entry entry, final int priority, final boolean enqueuToFront )
{
final long currentQueueFrame = queue.getCurrentFrame();
if ( entry.getEnqueueFrame() < currentQueueFrame )
{
entry.setEnqueueFrame( currentQueueFrame );
......@@ -310,7 +254,7 @@ public final class LoadingVolatileCache< K, V extends VolatileCacheValue > imple
*/
private void loadOrEnqueue( final Entry entry, final int priority, final boolean enqueuToFront )
{
final IoStatistics stats = cacheIoTiming.getThreadGroupIoStatistics();
final IoStatistics stats = CacheIoTiming.getIoStatistics();
final IoTimeBudget budget = stats.getIoTimeBudget();
final long timeLeft = budget.timeLeft( priority );
if ( timeLeft > 0 )
......@@ -388,7 +332,7 @@ public final class LoadingVolatileCache< K, V extends VolatileCacheValue > imple
private V value;
private final VolatileCacheValueLoader< ? extends V > loader;
private VolatileCacheValueLoader< ? extends V > loader;
/**
* When was this entry last enqueued for loading (see
......@@ -445,6 +389,7 @@ public final class LoadingVolatileCache< K, V extends VolatileCacheValue > imple
if ( !value.isValid() )
{
value = loader.load();
loader = null;
enqueueFrame = Long.MAX_VALUE;
cache.putSoft( key, this );
notifyAll();
......
package bdv.cache.iotiming;
import java.util.concurrent.ConcurrentHashMap;
/**
* Utilities for per {@link ThreadGroup} measuring and budgeting of time spent
* in (blocking) IO.
*
* @author Tobias Pietzsch &lt;tobias.pietzsch@gmail.com&gt;
*/
public class CacheIoTiming
{
private static final ConcurrentHashMap< ThreadGroup, IoStatistics > perThreadGroupIoStatistics = new ConcurrentHashMap<>();
public static IoStatistics getIoStatistics()
{
return getIoStatistics( Thread.currentThread().getThreadGroup() );
}
public static IoStatistics getIoStatistics( final ThreadGroup key )
{
IoStatistics statistics = perThreadGroupIoStatistics.get( key );
if ( statistics == null )
{
synchronized ( perThreadGroupIoStatistics )
{
statistics = perThreadGroupIoStatistics.get( key );
if ( statistics == null )
{
statistics = new IoStatistics();
perThreadGroupIoStatistics.put( key, statistics );
}
}
}
return statistics;
}
public static IoTimeBudget getIoTimeBudget()
{
return getIoStatistics().getIoTimeBudget();
}
public static IoTimeBudget getIoTimeBudget( final ThreadGroup key )
{
return getIoStatistics( key ).getIoTimeBudget();
}
private CacheIoTiming() {}
}
package bdv.cache.iotiming;
import java.util.concurrent.ConcurrentHashMap;
import net.imglib2.ui.util.StopWatch;
public class IoStatistics
{
private final ConcurrentHashMap< Thread, StopWatch > perThreadStopWatches = new ConcurrentHashMap<>();
private final StopWatch stopWatch;
private int numRunningThreads;
private long ioBytes;
private final IoTimeBudget ioTimeBudget;
public IoStatistics()
{
stopWatch = new StopWatch();
ioBytes = 0;
numRunningThreads = 0;
ioTimeBudget = new IoTimeBudget();
}
public synchronized void start()
{
getThreadStopWatch().start();
if( numRunningThreads++ == 0 )
stopWatch.start();
}
public synchronized void stop()
{
getThreadStopWatch().stop();
if( --numRunningThreads == 0 )
stopWatch.stop();
}
public void incIoBytes( final long n )
{
ioBytes += n;
}
public long getIoBytes()
{
return ioBytes;
}
public long getIoNanoTime()
{
return stopWatch.nanoTime();
}
public long getCumulativeIoNanoTime()
{
long sum = 0;
for ( final StopWatch w : perThreadStopWatches.values() )
sum += w.nanoTime();
return sum;
}
public IoTimeBudget getIoTimeBudget()
{
return ioTimeBudget;
}
private StopWatch getThreadStopWatch()
{
final Thread thread = Thread.currentThread();
StopWatch w = perThreadStopWatches.get( thread );
if ( w == null )
{
w = new StopWatch();
perThreadStopWatches.put( thread, w );
}
return w;
}
}
package bdv.cache.iotiming;
/**
* Budget of time that can be spent in blocking IO. The budget is grouped by
* priority levels, where level 0 is the highest priority. The budget for
* level <em>i &gt; j</em> must always be smaller-equal the budget for level
* <em>j</em>.
*
* For BDV, the time unit of {@link IoTimeBudget} values is nanoseconds.
*/
public class IoTimeBudget
{
private long[] budget;
public IoTimeBudget()
{
budget = new long[] { 0 };
}
/**
* (Re-)initialize the IO time budget, that is, the time that can be spent
* in blocking IO.
*
* @param partialBudget
* Initial budget for priority levels <em>0</em> through
* <em>n</em>. The budget for level <em>i&gt;j</em> must always
* be smaller-equal the budget for level <em>j</em>.
*/
public synchronized void reset( final long[] partialBudget )
{
if ( partialBudget == null || partialBudget.length == 0 )
clear();
else
{
if ( partialBudget.length == budget.length )
System.arraycopy( partialBudget, 0, budget, 0, budget.length );
else
budget = partialBudget.clone();
for ( int i = 1; i < budget.length; ++i )
if ( budget[ i ] > budget[ i - 1 ] )
budget[ i ] = budget[ i - 1 ];
}
}
/**
* Set the budget to 0 (for all levels).
*/
public synchronized void clear()
{
for ( int i = 0; i < budget.length; ++i )
budget[ i ] = 0;
}
/**
* Returns how much time is left for the specified priority level.
*
* @param level
* priority level. must be greater &ge; 0.
* @return time left for the specified priority level.
*/
public synchronized long timeLeft( final int level )
{
final int blevel = Math.min( level, budget.length - 1 );
return budget[ blevel ];
}
/**
* Use the specified amount of time of the specified level.
*
* {@code t} is subtracted from the budgets of level {@code level} and
* smaller. If by this, the remaining budget of {@code level} becomes
* smaller than the remaining budget of {@code level + 1}, then this is
* reduced too. (And the same for higher levels.)
*
* @param t
* how much time to use.
* @param level
* priority level. must be greater &ge; 0.
*/
public synchronized void use( final long t, final int level )
{
final int blevel = Math.min( level, budget.length - 1 );
int l = 0;
for ( ; l <= blevel; ++l )
budget[ l ] -= t;
for ( ; l < budget.length && budget[ l ] > budget[ l - 1 ]; ++l )
budget[ l ] = budget[ l - 1 ];
}
}
......@@ -31,7 +31,6 @@ package bdv.img.cache;
import bdv.cache.CacheControl;
import bdv.cache.CacheHints;
import bdv.cache.CacheIoTiming;
import bdv.cache.LoadingVolatileCache;
import bdv.cache.VolatileCacheValueLoader;
import bdv.cache.WeakSoftCache;
......@@ -104,6 +103,12 @@ public class VolatileGlobalCellCache implements CacheControl
}
}
private final WeakSoftCacheFactory cacheFactory = new WeakSoftCacheFactory();
private final BlockingFetchQueues< Loader > queue;
private final FetcherThreads fetchers;
protected final LoadingVolatileCache< Key, VolatileCell< ? > > volatileCache; // TODO rename
/**
......@@ -113,15 +118,18 @@ public class VolatileGlobalCellCache implements CacheControl
*/
public VolatileGlobalCellCache( final int maxNumLevels, final int numFetcherThreads )
{
volatileCache = new LoadingVolatileCache<>( maxNumLevels, numFetcherThreads );
queue = new BlockingFetchQueues<>( maxNumLevels );
fetchers = new FetcherThreads( queue, numFetcherThreads );
volatileCache = new LoadingVolatileCache<>( cacheFactory, queue );
}
/**
* pause all fetcher threads for the specified number of milliseconds.
*/
// TODO remove on next opportunity (when API is broken anyways...)
public void pauseFetcherThreadsFor( final long ms )
{
volatileCache.getFetcherThreads().pauseFetcherThreadsFor( ms );
fetchers.pauseFetcherThreadsFor( ms );
}
/**
......@@ -138,34 +146,8 @@ public class VolatileGlobalCellCache implements CacheControl
@Override
public void prepareNextFrame()
{
volatileCache.prepareNextFrame();
}
/**
* (Re-)initialize the IO time budget, that is, the time that can be spent
* in blocking IO per frame/
*
* @param partialBudget
* Initial budget (in nanoseconds) for priority levels 0 through
* <em>n</em>. The budget for level <em>i&gt;j</em> must always be
* smaller-equal the budget for level <em>j</em>. If <em>n</em>
* is smaller than the maximum number of mipmap levels, the
* remaining priority levels are filled up with budget[n].
*/
@Override
public void initIoTimeBudget( final long[] partialBudget )
{
volatileCache.initIoTimeBudget( partialBudget );
}
/**
* Get the {@link CacheIoTiming} that provides per thread-group IO
* statistics and budget.
*/
@Override
public CacheIoTiming getCacheIoTiming()
{
return volatileCache.getCacheIoTiming();
queue.clearToPrefetch();
cacheFactory.cleanUp();
}
/**
......@@ -175,6 +157,7 @@ public class VolatileGlobalCellCache implements CacheControl
public void clearCache()
{
volatileCache.invalidateAll();
queue.clear();
}
/**
......
......@@ -31,8 +31,8 @@ package bdv.img.cache;
import bdv.cache.CacheControl;
import bdv.cache.CacheHints;
import bdv.cache.CacheIoTiming.IoTimeBudget;
import bdv.cache.LoadingStrategy;
import bdv.cache.iotiming.IoTimeBudget;
import bdv.cache.util.BlockingFetchQueues;
import net.imglib2.img.Img;
import net.imglib2.img.ImgFactory;
......
......@@ -38,6 +38,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import bdv.cache.CacheControl;
import bdv.cache.LoadingStrategy;
import bdv.cache.iotiming.CacheIoTiming;
import bdv.img.cache.CachedCellImg;
import bdv.viewer.Interpolation;
import bdv.viewer.Source;
import bdv.viewer.render.MipmapOrdering.Level;
import bdv.viewer.render.MipmapOrdering.MipmapHints;
import bdv.viewer.state.SourceState;
import bdv.viewer.state.ViewerState;
import net.imglib2.Dimensions;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessible;
......@@ -55,15 +65,6 @@ import net.imglib2.ui.Renderer;
import net.imglib2.ui.SimpleInterruptibleProjector;
import net.imglib2.ui.TransformListener;
import net.imglib2.ui.util.GuiUtil;
import bdv.cache.CacheControl;
import bdv.cache.LoadingStrategy;
import bdv.img.cache.CachedCellImg;
import bdv.viewer.Interpolation;
import bdv.viewer.Source;
import bdv.viewer.render.MipmapOrdering.Level;
import bdv.viewer.render.MipmapOrdering.MipmapHints;
import bdv.viewer.state.SourceState;
import bdv.viewer.state.ViewerState;
/**
* A {@link Renderer} that uses a coarse-to-fine rendering scheme. First, a
......@@ -617,7 +618,7 @@ public class MultiResolutionRenderer
final int screenScaleIndex,
final ARGBScreenImage screenImage )
{
cacheControl.initIoTimeBudget( null ); // clear time budget such that prefetching doesn't wait for loading blocks.
CacheIoTiming.getIoTimeBudget().clear(); // clear time budget such that prefetching doesn't wait for loading blocks.
final List< SourceState< ? > > sourceStates = viewerState.getSources();
final List< Integer > visibleSourceIndices = viewerState.getVisibleSourceIndices();
VolatileProjector projector;
......@@ -650,7 +651,7 @@ public class MultiResolutionRenderer
}
previousTimepoint = viewerState.getCurrentTimepoint();
viewerState.getViewerTransform( currentProjectorTransform );
cacheControl.initIoTimeBudget( iobudget );
CacheIoTiming.getIoTimeBudget().reset( iobudget );
return projector;
}
......@@ -754,7 +755,7 @@ public class MultiResolutionRenderer
if ( hints.renewHintsAfterPaintingOnce() )
newFrameRequest = true;
}
return new VolatileHierarchyProjector<>( renderList, source.getConverter(), screenImage, maskArray, numRenderingThreads, renderingExecutorService, cacheControl.getCacheIoTiming() );
return new VolatileHierarchyProjector<>( renderList, source.getConverter(), screenImage, maskArray, numRenderingThreads, renderingExecutorService );
}
private static < T > RandomAccessible< T > getTransformedSource( final ViewerState viewerState, final Source< T > source, final AffineTransform3D screenScaleTransform, final int mipmapIndex )
......
......@@ -38,8 +38,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import bdv.cache.CacheIoTiming;
import bdv.cache.CacheIoTiming.IoStatistics;
import bdv.cache.iotiming.CacheIoTiming;
import bdv.cache.iotiming.IoStatistics;
import net.imglib2.Cursor;
import net.imglib2.FinalInterval;
import net.imglib2.IterableInterval;
......@@ -131,22 +131,14 @@ public class VolatileHierarchyProjector< A extends Volatile< ? >, B extends Nume
*/
protected final AtomicBoolean interrupted = new AtomicBoolean();
/**
* The {@link CacheIoTiming} that is used to determine
* {@link #getLastFrameIoNanoTime() io time} and
* {@link #getLastFrameRenderNanoTime() render time}.
*/
protected final CacheIoTiming cacheIoTiming;
public VolatileHierarchyProjector(
final List< ? extends RandomAccessible< A > > sources,
final Converter< ? super A, B > converter,
final RandomAccessibleInterval< B > target,
final int numThreads,
final ExecutorService executorService,
final CacheIoTiming cacheIoTiming )
final ExecutorService executorService )
{
this( sources, converter, target, new byte[ ( int ) ( target.dimension( 0 ) * target.dimension( 1 ) ) ], numThreads, executorService, cacheIoTiming );
this( sources, converter, target, new byte[ ( int ) ( target.dimension( 0 ) * target.dimension( 1 ) ) ], numThreads, executorService );
}
public VolatileHierarchyProjector(
......@@ -155,8 +147,7 @@ public class VolatileHierarchyProjector< A extends Volatile< ? >, B extends Nume
final RandomAccessibleInterval< B > target,
final byte[] maskArray,
final int numThreads,
final ExecutorService executorService,
final CacheIoTiming cacheIoTiming )
final ExecutorService executorService )
{
super( Math.max( 2, sources.get( 0 ).numDimensions() ), converter, target );
......@@ -181,7 +172,6 @@ public class VolatileHierarchyProjector< A extends Volatile< ? >, B extends Nume
this.numThreads = numThreads;
this.executorService = executorService;
this.cacheIoTiming = cacheIoTiming;
lastFrameRenderNanoTime = -1;
clearMask();
......@@ -244,7 +234,7 @@ public class VolatileHierarchyProjector< A extends Volatile< ? >, B extends Nume
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
final IoStatistics iostat = cacheIoTiming.getThreadGroupIoStatistics();
final IoStatistics iostat = CacheIoTiming.getIoStatistics();
final long startTimeIo = iostat.getIoNanoTime();
final long startTimeIoCumulative = iostat.getCumulativeIoNanoTime();
// final long startIoBytes = iostat.getIoBytes();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment