public class ApfloatContext extends Object implements Cloneable
All environment related settings of an apfloat implementation are accessed
through an ApfloatContext
. Such settings include for example
the implementation provider class, maximum memory size to be used, and
the file names that are used for temporary files.
For performance reasons, access to an ApfloatContext
is not
synchronized. Presumably, this won't be a problem in most cases. But, if
the code needs to concurrently modify and access an ApfloatContext, all
access to it should be externally synchronized.
At simplest, there is just one ApfloatContext
, the global
apfloat context. All settings in your application are retrieved through
it. The global context is created when the ApfloatContext
class is loaded, and it's thus always available.
Values for the different settings in the global apfloat context are specified
in the apfloat.properties
file, found in the class path. Since
they are loaded via a ResourceBundle
named "apfloat", you can
alternatively deploy a ResourceBundle
class named "apfloat" in
your class path to avoid having a .properties file, or to define properties
dynamically at run time.
The different settings that can be specified in the apfloat.properties
file are as follows:
builderFactory
, name of the class set as in setBuilderFactory(BuilderFactory)
defaultRadix
, set as in setDefaultRadix(int)
maxMemoryBlockSize
, set as in setMaxMemoryBlockSize(long)
cacheL1Size
, set as in setCacheL1Size(int)
cacheL2Size
, set as in setCacheL2Size(int)
cacheBurst
, set as in setCacheBurst(int)
memoryThreshold
, set as in setMemoryThreshold(long)
shredMemoryTreshold
, set as in setSharedMemoryTreshold(long)
blockSize
, set as in setBlockSize(int)
numberOfProcessors
, set as in setNumberOfProcessors(int)
filePath
, set as in setProperty(String,String)
with property name FILE_PATH
fileInitialValue
, set as in setProperty(String,String)
with property name FILE_INITIAL_VALUE
fileSuffix
, set as in setProperty(String,String)
with property name FILE_SUFFIX
cleanupAtExit
, set as in setCleanupAtExit(boolean)
An example apfloat.properties
file could contain the following:
builderFactory=org.apfloat.internal.IntBuilderFactory defaultRadix=10 maxMemoryBlockSize=50331648 cacheL1Size=8192 cacheL2Size=262144 cacheBurst=32 memoryThreshold=65536 sharedMemoryTreshold=65536 blockSize=65536 numberOfProcessors=1 filePath= fileInitialValue=0 fileSuffix=.ap cleanupAtExit=trueThe total memory size and the number of processors are detected automatically, as reported by the Java runtime, if they are not specified in the configuration bundle.
If you need to create a complex multithreaded application that performs apfloat calculations in parallel using multiple threads, you may need to change the ApfloatContext settings for the different working threads.
If thread-specific apfloat contexts are not specified, all threads will use
the global context. To set a thread specific context, you would typically
create a clone()
of the global (or other parent) context, and then
set that context to the thread using setThreadContext(ApfloatContext,Thread)
.
Note that if you do not create a clone of the context, the same context will still
be used, since it's passed by reference.
Typically you may need to set the following properties for each thread:
setNumberOfProcessors(int)
: Since the number of physical
processors available is fixed, you may want to limit the amount
of processors each thread can use. In many cases you will want each
thread to use exactly one processor, and create as many threads as
there are processors.setMaxMemoryBlockSize(long)
: The physical memory is global
and its amount is fixed as well. Since all threads share the global
memory, you may want to limit the maximum amount of memory each thread
can use. If you do this, you will probably just split the amount of
memory between the threads, e.g. by dividing it equally. In this case
you should set each thread to have a separate shared memory lock with
setSharedMemoryLock(Object)
. In this solution all threads can
allocate their maximum allowed memory block at the same time, and still
the VM won't run out of memory.setMaxMemoryBlockSize(long)
nor setSharedMemoryLock(Object)
.
This way all threads can access the maximum amount of physical memory
available. The drawback is that the threads will synchronize on the
same memory block, so only one thread can use it at a time. This can
have a major effect on performance, if threads are idle, waiting to acquire
the shared memory lock for most of the time. To work around this, some
mechanism can be set up for pooling the threads competing for the same
lock, and executing the task using parallel threads from the thread pool.
For example the default apfloat multiplication algorithm uses such a
mechanism. Note that synchronization against the shared memory lock
will be used for all data blocks larger than the shared memory
treshold (see getSharedMemoryTreshold()
).setFilenameGenerator(FilenameGenerator)
: When you clone an
ApfloatContext, the filename generator is by default shared. For most
situations this is fine. If you for some reason want to separate
the files generated in each thread, you can just set a new
FilenameGenerator for each thread. In this case it's essential to
configure the FilenameGenerators not to generate conflicting file
names. You can do this easily by specifying a different directory or
file suffix for each filename generator, or by specifying a different
starting value for the file names (e.g. 1000000, 2000000, 3000000, ...).The other settings are generally global and do not typically need to be set differently for each thread.
Unfortunately, Java doesn't allow detecting automatically many of the
settings, such as cache sizes. Also, for optimal performance, it would
usually be desirable to set each thread's processor affinity (which
physical processor runs which thread), which is also not possible.
If these features are added to the Java platform in the future, they
may be added to the ApfloatContext
API as well.
Modifier and Type | Field and Description |
---|---|
static String |
BLOCK_SIZE
Property name for specifying the I/O block size.
|
static String |
BUILDER_FACTORY
Property name for specifying the apfloat builder factory class.
|
static String |
CACHE_BURST
Property name for specifying the level 1 cache burst size.
|
static String |
CACHE_L1_SIZE
Property name for specifying the level 1 cache size.
|
static String |
CACHE_L2_SIZE
Property name for specifying the level 2 cache size.
|
static String |
CLEANUP_AT_EXIT
Property name for specifying if clean-up should be done at program exit.
|
static String |
DEFAULT_RADIX
Property name for specifying the default radix.
|
static String |
FILE_INITIAL_VALUE
Property name for specifying the temporary file initial value.
|
static String |
FILE_PATH
Property name for specifying the temporary file path.
|
static String |
FILE_SUFFIX
Property name for specifying the temporary file suffix.
|
static String |
MAX_MEMORY_BLOCK_SIZE
Property name for specifying the maximum memory block size.
|
static String |
MEMORY_THRESHOLD
Property name for specifying the apfloat memory threshold.
|
static String |
MEMORY_TRESHOLD
Deprecated.
Use
MEMORY_THRESHOLD . |
static String |
NUMBER_OF_PROCESSORS
Property name for specifying the number of processors available.
|
static String |
SHARED_MEMORY_TRESHOLD
Property name for specifying the apfloat shared memory threshold.
|
Constructor and Description |
---|
ApfloatContext(Properties properties)
Create a new ApfloatContext using the specified properties.
|
Modifier and Type | Method and Description |
---|---|
static void |
clearThreadContexts()
Removes all thread-specific ApfloatContexts.
|
Object |
clone()
Creates a copy of this object.
|
Object |
getAttribute(String name)
Get an arbitrary object as an attribute for this ApfloatContext.
|
Enumeration<String> |
getAttributeNames()
Get names of all attributes for this ApfloatContext.
|
int |
getBlockSize()
Get the I/O block size.
|
BuilderFactory |
getBuilderFactory()
Get the BuilderFactory.
|
int |
getCacheBurst()
Get the level 1 cache burst size.
|
int |
getCacheL1Size()
Get the level 1 cache size.
|
int |
getCacheL2Size()
Get the level 2 cache size.
|
boolean |
getCleanupAtExit()
Get if clean-up should be performed at the time the program exits.
|
static ApfloatContext |
getContext()
Get the ApfloatContext for the calling thread.
|
static ExecutorService |
getDefaultExecutorService()
Returns a new instance of a default ExecutorService.
|
int |
getDefaultRadix()
Get the default radix.
|
ExecutorService |
getExecutorService()
Get the ExecutorService.
|
FilenameGenerator |
getFilenameGenerator()
Get the FilenameGenerator.
|
static ApfloatContext |
getGlobalContext()
Get the global ApfloatContext.
|
long |
getMaxMemoryBlockSize()
Get the maximum memory block size.
|
long |
getMemoryThreshold()
Get the memory threshold.
|
int |
getMemoryTreshold()
Deprecated.
Use
getMemoryThreshold() . |
int |
getNumberOfProcessors()
Get the number of processors that should be used for parallel calculations.
|
Properties |
getProperties()
Get the values of all properties as strings.
|
String |
getProperty(String propertyName)
Get the value of a property as string.
|
String |
getProperty(String propertyName,
String defaultValue)
Get the value of a property as string, with the provided default
value if the property is not set.
|
Object |
getSharedMemoryLock()
Get the shared memory lock object.
|
long |
getSharedMemoryTreshold()
Get the shared memory treshold.
|
static ApfloatContext |
getThreadContext()
Get the thread-specific ApfloatContext for the calling thread.
|
static ApfloatContext |
getThreadContext(Thread thread)
Get the thread-specific ApfloatContext for the specified thread.
|
static Properties |
loadProperties()
Loads properties from a properties file or resource bundle.
|
Object |
removeAttribute(String name)
Remove an attribute from this ApfloatContext.
|
static void |
removeThreadContext()
Removes the thread-specific context for the current thread.
|
static void |
removeThreadContext(Thread thread)
Removes the thread-specific context for the specified thread.
|
Object |
setAttribute(String name,
Object value)
Set an arbitrary object as an attribute for this ApfloatContext.
|
void |
setBlockSize(int blockSize)
Set the efficient I/O block size in bytes for
this context.
|
void |
setBuilderFactory(BuilderFactory builderFactory)
Set the BuilderFactory.
|
void |
setCacheBurst(int cacheBurst)
Set the L1 cache burst block size in bytes.
|
void |
setCacheL1Size(int cacheL1Size)
Set the L1 cache size in bytes.
|
void |
setCacheL2Size(int cacheL2Size)
Set the L2 cache size in bytes.
|
void |
setCleanupAtExit(boolean cleanupAtExit)
Set if clean-up should be performed at the time the program exits.
|
void |
setDefaultRadix(int radix)
Set the default radix.
|
void |
setExecutorService(ExecutorService executorService)
Set the ExecutorService.
|
void |
setFilenameGenerator(FilenameGenerator filenameGenerator)
Set the FilenameGenerator.
|
void |
setMaxMemoryBlockSize(long maxMemoryBlockSize)
Set the maximum allowed memory block size in bytes.
|
void |
setMemoryThreshold(long memoryThreshold)
Set the maximum size of apfloats in bytes that are
stored in memory within this context.
|
void |
setMemoryTreshold(int memoryThreshold)
Deprecated.
|
void |
setNumberOfProcessors(int numberOfProcessors)
Set the number of processors available to parallel calculations using
this context.
|
void |
setProperties(Properties properties)
Set the values of all properties as strings.
|
void |
setProperty(String propertyName,
String propertyValue)
Set the value of a property as string.
|
void |
setSharedMemoryLock(Object lock)
Set the shared memory lock object.
|
void |
setSharedMemoryTreshold(long sharedMemoryTreshold)
Set the maximum size of apfloats in bytes that can be used
without synchronizing against the shared memory lock.
|
static void |
setThreadContext(ApfloatContext threadContext)
Set the thread-specific ApfloatContext for the calling thread.
|
static void |
setThreadContext(ApfloatContext threadContext,
Thread thread)
Set the thread-specific ApfloatContext for the specified thread.
|
public static final String BUILDER_FACTORY
public static final String DEFAULT_RADIX
public static final String MAX_MEMORY_BLOCK_SIZE
public static final String CACHE_L1_SIZE
public static final String CACHE_L2_SIZE
public static final String CACHE_BURST
public static final String MEMORY_THRESHOLD
@Deprecated public static final String MEMORY_TRESHOLD
MEMORY_THRESHOLD
.public static final String SHARED_MEMORY_TRESHOLD
public static final String BLOCK_SIZE
public static final String NUMBER_OF_PROCESSORS
public static final String FILE_PATH
public static final String FILE_INITIAL_VALUE
public static final String FILE_SUFFIX
public static final String CLEANUP_AT_EXIT
public ApfloatContext(Properties properties) throws ApfloatConfigurationException
properties
- The properties for the ApfloatContext.ApfloatConfigurationException
- If a property value can't be converted to the correct type.public static ApfloatContext getContext()
public static ApfloatContext getGlobalContext()
public static ApfloatContext getThreadContext()
null
if one has not been specified.public static ApfloatContext getThreadContext(Thread thread)
thread
- The thread whose ApfloatContext is to be returned.null
if one has not been specified.public static void setThreadContext(ApfloatContext threadContext)
threadContext
- The ApfloatContext for the calling thread.public static void setThreadContext(ApfloatContext threadContext, Thread thread)
threadContext
- The ApfloatContext for the specified thread.thread
- The thread whose ApfloatContext is to be set.public static void removeThreadContext()
public static void removeThreadContext(Thread thread)
thread
- The thread whose ApfloatContext is to be removed.public static void clearThreadContexts()
public BuilderFactory getBuilderFactory()
public void setBuilderFactory(BuilderFactory builderFactory)
builderFactory
- The BuilderFactory for this ApfloatContext.public FilenameGenerator getFilenameGenerator()
public void setFilenameGenerator(FilenameGenerator filenameGenerator)
filenameGenerator
- The FilenameGenerator for this ApfloatContext.public int getDefaultRadix()
public void setDefaultRadix(int radix)
radix
- The default radix for this ApfloatContext.public long getMaxMemoryBlockSize()
setMaxMemoryBlockSize(long)
public void setMaxMemoryBlockSize(long maxMemoryBlockSize)
If you set the value of this parameter too low,
performance will suffer greatly as data is unnecessarily
paged to disk. If you set this value too high, your
application can crash with an OutOfMemoryError
.
The default value for this setting is 80% of the total memory
available to the VM at application startup, as reported by
Runtime.totalMemory()
, rounded down to the nearest
power of two or three times a power of two.
maxMemoryBlockSize
- Maximum allocated memory block size in bytes.public int getCacheL1Size()
setCacheL1Size(int)
public void setCacheL1Size(int cacheL1Size)
This setting has a minor performance impact on some memory intensive operations. Unless you really want to tweak the performance, it's better to not touch this setting.
The default value for this setting is 8kB.
cacheL1Size
- The level 1 cache size in bytes.public int getCacheL2Size()
setCacheL2Size(int)
public void setCacheL2Size(int cacheL2Size)
The default value for this setting is 256kB.
cacheL2Size
- The level 2 cache size in bytes.public int getCacheBurst()
setCacheBurst(int)
public void setCacheBurst(int cacheBurst)
Some common values are:
This setting has a minor performance impact on some memory intensive operations. Unless you really want to tweak the performance, it's usually better to not touch this setting. Though, if you have e.g. a Pentium 4 processor, you may want to increase the value of this setting to 64 from the default value of 32.
cacheBurst
- The number of bytes in a L1 cache line.@Deprecated public int getMemoryTreshold()
getMemoryThreshold()
.
If the value is larger than the maximum value that can be presented
in an integer, then Integer.MAX_VALUE
is returned.
@Deprecated public void setMemoryTreshold(int memoryThreshold)
setMemoryThreshold(long)
.memoryThreshold
- The number of bytes that apfloats that are stored in memory will at most have within this context.public long getMemoryThreshold()
public void setMemoryThreshold(long memoryThreshold)
If the memory threshold is too small, performance will suffer as
small numbers are stored to disk, and the amount of disk I/O
overhead becomes significant. On the other hand, if the memory
treshold is too big, you can get an OutOfMemoryError
.
The optimal value depends greatly on each application. Obviously, if you have plenty of heap space and don't create too many too big numbers you are not likely to have problems. The default value of this setting is 64kB, or the maximum heap size divided by 1024, whichever is larger.
memoryThreshold
- The number of bytes that apfloats that are stored in memory will at most have within this context.public long getSharedMemoryTreshold()
setSharedMemoryTreshold(long)
public void setSharedMemoryTreshold(long sharedMemoryTreshold)
If only one thread is used then this setting has no effect.
If multiple threads are used, and this setting is too small,
performance will suffer as the synchronization blocking and
other overhead becomes significant. On the other hand, if the
numbers are being stored in memory, and the shared memory
treshold is too big, you can get an OutOfMemoryError
.
The optimal value depends on the application and the way parallelism is used. As a rule of thumb, this should be set to a value that is the maximum memory block size divided by the number of parallel threads. The default is somewhat more conservatively this number divided by 32.
sharedMemoryTreshold
- The number of bytes that apfloats will at most have, without synchronizing against the shared memory lock, within this context.public int getBlockSize()
setBlockSize(int)
public void setBlockSize(int blockSize)
If the block size is too small, the overhead of each I/O call will
definetely have an adverse effect on performance. Setting the block
size very big will not affect performance significantly, but can
increase intermediate memory consumption a lot, possibly resulting
in running out of memory with an OutOfMemoryError
. A
recommended minimum value is at least a few kilobytes.
In many places, data in files is accessed in reverse order, fetching blocks of this size. Probably the optimal value of this setting is roughly half of the read-ahead buffer size of you hard disk. The default value is 64kB.
blockSize
- The I/O block size in bytes to be used in calculations using this context.public int getNumberOfProcessors()
setNumberOfProcessors(int)
public void setNumberOfProcessors(int numberOfProcessors)
Note that if you change the number of processors after the library has
been initialized, the number of threads available to the ExecutorService
is not changed. If you want to change that too, it can be done easily with
setExecutorService(ApfloatContext.getDefaultExecutorService())
.
numberOfProcessors
- Number of processors available to parallel calculations using this context.getDefaultExecutorService()
,
setExecutorService(ExecutorService)
public boolean getCleanupAtExit()
true
if clean-up will be done at JVM exit, or false
if not.setCleanupAtExit(boolean)
public void setCleanupAtExit(boolean cleanupAtExit)
true
.
For example unsigned applets must have this property set to false
,
since they do not have access to setting shutdown hooks.
Note that if this setting is ever set to true
in any
ApfloatContext
(and never set to false
subsequently in that context), then clean-up will be performed.
Also note that having the shutdown hook set will prevent class garbage collection i.e. the apfloat classes can't be unloaded if the shutdown hook still references the ApfloatContext class. If class unloading is desired then the cleanupAtExit property should be set to false first.
cleanupAtExit
- true
if clean-up should be done at JVM exit, or false
if not.public String getProperty(String propertyName)
propertyName
- The name of the property.String
.public String getProperty(String propertyName, String defaultValue)
propertyName
- The name of the property.defaultValue
- The default value to be returned, if the property is not set.String
.public void setProperty(String propertyName, String propertyValue) throws ApfloatConfigurationException
propertyName
- The name of the property.propertyValue
- The value of the property as a String
.ApfloatConfigurationException
- If the property value can't be converted to the correct type.public Properties getProperties()
public Object getSharedMemoryLock()
public void setSharedMemoryLock(Object lock)
The object is not used for anything else than synchronization, so the
class of the object should really be java.lang.Object
. One
would typically call this method e.g. as
ctx.setSharedMemoryLock(new Object())
.
lock
- The object on which large memory block allocation and access should be synchronized.public ExecutorService getExecutorService()
By default the ExecutorService is a thread pool that is shared by all the ApfloatContexts. The threads in the pool are daemon threads so the thread pool requires no clean-up at shutdown time.
getDefaultExecutorService()
public void setExecutorService(ExecutorService executorService)
If a custom ExecutorService is used, e.g. a thread pool, then the number
of available threads in the pool should match the number of processors
set to all ApfloatContexts with setNumberOfProcessors(int)
.
Note that if a custom ExecutorService that requires shutdown is used, it is the caller's responsibility to clean up the ExecutorService at shutdown.
executorService
- The ExecutorService.getDefaultExecutorService()
public Object getAttribute(String name)
name
- Name of the attribute.null
if the attribute doesn't exist.public Object setAttribute(String name, Object value)
name
- Name of the attribute.value
- Value of the attribute.null
if the attribute didn't exist.public Object removeAttribute(String name)
name
- Name of the attribute.null
if the attribute didn't exist.public Enumeration<String> getAttributeNames()
public static Properties loadProperties() throws ApfloatRuntimeException
ResourceBundle
by the name "apfloat" is
located, then all properties found from that resource bundle
are put to a Properties
object.
The resource bundle is found basically using the following logic
(note that this is standard Java ResourceBundle
functionality), in this order whichever is found first:
apfloat
(that should be a subclass of ResourceBundle
), in the current class pathProperties
object, if the resource bundle is not found.ApfloatRuntimeException
public static ExecutorService getDefaultExecutorService()
The default executor service is a thread-limited pool
where the number of threads is one less than the number
of processors set with setNumberOfProcessors(int)
.
public void setProperties(Properties properties) throws ApfloatConfigurationException
properties
- The properties.ApfloatConfigurationException
- If a property value can't be converted to the correct type.public Object clone()
The clone has the same BuilderFactory and FilenameGenerator members and the same shared memory lock and ExecutorService as the original ApfloatContext.
A shallow copy of the property set and the attribute set is created. Thus setting a property or attribute on the clone will not set it in the original object. Since the actual attributes (values) are shared, if an attribute is mutable and is modified in the clone, the modified value will appear in the original also.
Copyright © 2017. All rights reserved.