Python DAQmx Task Takes a Long Time to Execute

Updated Jan 17, 2023

Reported In

Driver

  • NI-DAQmx

Other

  • Python

Issue Details

  • I am using the Python DAQmx API to acquire or generate data from my DAQ hardware. Every time I run my code, I notice that the writing or reading tasks upwards of 200 ms to complete. How can I reduce the execution time?
  • I am writing an array of values to my DAQ hardware using the Python API. Even though I am writing a small number of samples, my code always takes a few hundred milliseconds to complete. Is there a way to make it faster?

Solution

The execution speed of your Python code will depend on a number of factors, including:
  • How the API is called.
  • The choice of API used for the task.
  • Software limitations.
To determine whether your execution speed can be improved, work through the steps below:

1. Minimise the number of times the task is opened and closed.
  • When a task is created and configured, Python must locate and load the DLL associated with initialisation. This will add time to the execution.
  • If possible, initialise the task once at the beginning, and repeat read/write operations without closing or re-initialisation.
  • Note: a DAQmx task should be opened once and closed once when you're finished working with the hardware.
2. If using analog inputs/outputs, experiment with stream_readers and stream_writers. 3. Ensure that you are timing the task correctly.
  • Import a Python module to time specific sections of code. Note: a common module is the datetime module.
  • Obtain the time before a function and again immediately after the function to calculate the execution time. Repeat this with each function to determine which function is taking the longest to execute.
  • Below is an example of timing a DAQmx write.
import nidaqmx
import datetime

with nidaqmx.Task() as task:
    #get module and channels
    module1 = nidaqmx.system.System().devices[1].ao_physical_chans.all.name
    task.ao_channels.add_ao_current_chan(module1)

    #configure timing
    task.timing.samp_timing_type = nidaqmx.constants.SampleTimingType.SAMPLE_CLOCK
    acquis_type = nidaqmx.constants.AcquisitionType.FINITE
    task.timing.cfg_samp_clk_timing(rate=24000,sample_mode=acquis_type,samps_per_chan=24)
  
    #obtain start time, execute a write function, and then obtain the end time
    st = datetime.datetime.now()
    print(task.write([[0.001,0.002,0.003], [0.004,0.005,0.006], [0.007,0.008,0.009],[0.001,0.002,0.003], [0.004,0.005,0.006], [0.007,0.008,0.009],[0.001,0.002,0.003], [0.004,0.005,0.006]], auto_start=True))
    et = datetime.datetime.now()
    
    #calculate the difference between the start and end time, and print the result
    ft = et - st
    print(ft.microseconds)



4. Consider whether the following software limitations are contributing to your execution speed.
  • Windows operating systems are undeterministic. This is a result of the background tasks, updates and processes that are constantly running and cannot be prevented. As a result, it is expected that code will take at least a few milliseconds to complete (potentially more, depending on the complexity of the code).
  • The Python API is a wrapper on top of C API. As a result, Python must call into DLLs to execute each function. Each DLL requires processor time, so consider modifying your code to call into as few DLLs as possible.
  • The PC's CPU load will have an impact on code execution time. If the PC is running background applications, processes or updates, the code will take longer to execution.