Platforms: Windows, macOS, Linux
Computer provides access to OS and Process level functionality:
Read the current time in sec.msec format. The time base used is shared by the ioHub and PsychoPy processes.
Access the iohub and psychopy psutil.Process objects
Get / set process priority and affinity.
Read system memory and CPU usage
Computer contains only static methods and class attributes. Therefore all supported functionality can be accessed directly from the Computer class itself; an instance of the class never needs to be created.
Auto sets the PsychoPy Process and ioHub Process affinities based on some very simple logic.
It is not known at this time if the implementation of this method makes any sense in terms of actually improving performance. Field tests and feedback will need to occur, based on which the algorithm can be improved.
Currently:
If the system is detected to have 1 processing unit, or greater
than 8 processing units, nothing is done by the method. * For a system that has two processing units, the PsychoPy Process is assigned to index 0, ioHub Process assigned to 1. * For a system that has four processing units, the PsychoPy Process is assigned to index’s 0,1 and the ioHub Process assigned to 2,3. * For a system that has eight processing units, the PsychoPy Process is assigned to index 2,3, ioHub Process assigned to 4,5. All other processes running on the OS are attempted to be assigned to indexes 0,1,6,7.
None –
None
The number of cpu cores available on the computer. Hyperthreads are NOT included.
Access to the psutil.Process class for the current system Process.
Return a float representing the current CPU utilization as a percentage.
Get the current / Local process.
On Windows and Linux, this is a psutil.Process class instance.
None –
Process object for the current system process.
Returns a list of ‘processor’ ID’s (from 0 to Computer.processing_unit_count-1) that the current (calling) process is able to run on.
None –
None
Get the ioHub Process.
On Windows and Linux, this is a psutil.Process class instance.
None –
Process object for the ioHub Process.
Return a class containing information about current memory usage.
None –
(total=long, available=long, percent=float, used=long, free=long)
vmem
Where:
vmem.total: the total amount of memory in bytes.
vmem.available: the available amount of memory in bytes.
vmem.percent: the percent of memory in use by the system.
vmem.used: the used amount of memory in bytes.
vmem.free: the amount of memory that is free in bytes.On Windows,
this is the same as vmem.available.
Returns the current processes priority as a string.
This method is not supported on OS X.
‘normal’, ‘high’, or ‘realtime’
Retrieve the current PsychoPy Process affinity list and ioHub Process affinity list.
For example, on a 2 core CPU with hyper-threading, the possible ‘processor’ list would be [0,1,2,3], and by default both the PsychoPy and ioHub Processes can run on any of these ‘processors’, so:
psychoCPUs,ioHubCPUS=Computer.getProcessAffinities()
print psychoCPUs,ioHubCPUS
>> [0,1,2,3], [0,1,2,3]
If Computer.setProcessAffinities was used to set the PsychoPy Process to core 1 (index 0 and 1) and the ioHub Process to core 2 (index 2 and 3), with each using both hyper threads of the given core, the set call would look like:
Computer.setProcessAffinities([0,1],[2,3])
psychoCPUs,ioHubCPUS=Computer.getProcessAffinities()
print psychoCPUs,ioHubCPUS
>> [0,1], [2,3]
If the ioHub is not being used (i.e self.hub is None), then only the PsychoPy Process affinity list will be returned and None will be returned for the ioHub Process affinity:
psychoCPUs,ioHubCPUS=Computer.getProcessAffinities()
print psychoCPUs,ioHubCPUS
>> [0,1,2,3], None
But in this case, why are you using the ioHub package at all? ;)
This method is not supported on OS X.
Returns a list of ‘processor’ ID’s (from 0 to Computer.processing_unit_count-1) that the process with the provided processID is able to run on.
Return the number of processing units available on the current computer. Processing Units include: cpu’s, cpu cores, and hyper threads.
Notes:
processing_unit_count = num_cpus*num_cores_per_cpu*num_hyperthreads.
For single core CPU’s, num_cores_per_cpu = 1.
For CPU’s that do not support hyperthreading, num_hyperthreads =
1, otherwise num_hyperthreads = 2.
None –
the number of processing units on the computer.
Returns the current sec.msec-msec time of the system.
The underlying timer that is used is based on OS and Python version. Three requirements exist for the ioHub time base implementation:
The Python interpreter does not apply an offset to the times
returned based on when the timer module being used was loaded or when the timer function first called was first called. * The timer implementation used must be monotonic and report elapsed time between calls, ‘not’ CPU usage time. * The timer implementation must provide a resolution of 50 usec or better.
Given the above requirements, ioHub selects a timer implementation as follows:
On Windows, the Windows Query Performance Counter API is used
using ctypes access. * On other OS’s, if the Python version being used is 2.6 or lower, time.time is used. For Python 2.7 and above, the timeit.default_timer function is used.
None –
None
True if the current process is currently in high or real-time priority mode (enabled by calling Computer.setPriority()).
The psutil Process object for the ioHub Process.
The OS process ID of the ioHub Process.
True if the current process is the ioHub Server Process. False if the current process is the Experiment Runtime Process.
The name of the current operating system Python is running on.
Attribute representing the number of processing units available on the current computer. This includes cpu’s, cpu cores, and hyperthreads.
processing_unit_count = num_cpus * cores_per_cpu * num_hyperthreads
num_cpus: Number of CPU chips on the motherboard (usually 1 now).
cores_per_cpu: Number of processing cores per CPU (2,4 is common)
num_hyperthreads: Hyper-threaded cores = 2, otherwise 1.
If Computer class is on the iohub server process, psychopy_process is the psychopy process created from the pid passed to iohub on startup. The iohub server checks that this process exists (server.checkForPsychopyProcess()) and shuts down if it does not.
32 or 64. Note that when a Python 32 bit runtime is used a 64 bit OS sysbits will equal 32.
Python Env. bits
Sets the affinity for all OS Processes other than those specified in the exclude_process_id_list, to the processing unit indexes specified in processor_list. Valid values in the processor_list are between 0 to Computer.processing_unit_count-1.
exclude_process_id_list should be a list of OS Process ID integers, or an empty list (indicating to set the affiinty to all processing units).
Note that the OS may not allow the calling process to set the affinity of every other process running on the system. For example, some system level processing can not have their affinity set by a user level application.
However, in general, many processes can have their affinity set by another user process.
Sets the list of ‘processor’ ID’s (from 0 to Computer.processing_unit_count-1) that the current (calling) process should only be allowed to run on.
processorList (list) – list of int processor ID’s to set the
processors. (current Process affinity to. An empty list means all) –
None
Attempts to change the current processes priority based on level. Supported levels are:
‘normal’: sets the current process priority to
NORMAL_PRIORITY_CLASS on Windows, or to the processes original nice value on Linux. * ‘high’: sets the current process priority to HIGH_PRIORITY_CLASS on Windows, or to a nice value of -10 value on Linux. * ‘realtime’: sets the current process priority to REALTIME_PRIORITY_CLASS on Windows, or to a nice value of -18 value on Linux.
If level is ‘normal’, Python GC is also enabled. If level is ‘high’ or ‘realtime’, and disable_gc is True, then the Python garbage collection (GC) thread is suspended.
This method is not supported on OS X.
Priority level of process when method returns.
Sets the processor affinity for the PsychoPy Process and the ioHub Process.
For example, on a 2 core CPU with hyper-threading, the possible ‘processor’ list would be [0,1,2,3], and by default both the experiment and ioHub server processes can run on any of these ‘processors’, so to have both processes have all processors available (which is the default), you would call:
Computer.setProcessAffinities([0,1,2,3], [0,1,2,3])
# check the process affinities
psychoCPUs,ioHubCPUS=Computer.getProcessAffinities()
print psychoCPUs,ioHubCPUS
>> [0,1,2,3], [0,1,2,3]
based on the above CPU example.
If setProcessAffinities was used to set the experiment process to core 1 (index 0,1) and the ioHub server process to core 2 (index 2,3), with each using both hyper threads of the given core, the set call would look like:
Computer.setProcessAffinities([0,1],[2,3])
# check the process affinities
psychoCPUs,ioHubCPUS=Computer.getProcessAffinities()
print psychoCPUs,ioHubCPUS
>> [0,1], [2,3]
None
The computer Device is enabled automatically and has no configuration settings in the iohub_config.yaml.
The Computer Device does not generate any ioHub Events.
None at this time.