You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Is PyopenCL slower than its counterpart C OpenCL #499
I do not see a PyOpenCL forum online, so I post my question here.
I am working on a project to port my C OpenCL code to PyOpenCL. Is the speed of executing opencl kernels slowers in PyOpenCL than in C?
My tests show that my pyopencl is like 10-20% slower than c opencl. I read a post online saying pyopencl is like 28 times slower than c.
PyOpenCL is not involved in the execution of the kernels. The actual on-device kernel execution time should be exactly the same between a C program using OpenCL and a Python program using PyOpenCL. If that's not the case, something is very wrong.
This means that PyOpenCL is a good fit if your code spends most of its time executing kernel code (IMO: as it should!). If the kernel times are so short that kernels complete faster than Python can enqueue them, then there can be a performance impact.
my application spends most of the time on device (it is called computational fluid dynamics, in case you wonder 😄 ). I only counted the time the kernel is executed. To be specific,
I compiled all my kernels from program and save them into a list kernels.
Interestingly, I got same results between C OpenCL and PyOpenCL. So, I do not think I made any programming mistakes. But I might not use the PyOpenCL in the way it is supposed to.
Could you please comment on which part I should examine my code?
P.S. would it make any difference if i do the following
Are you saying your kernel times are different? Switch your command queue to enable profiling and get kernel execution times in both settings. They should match pretty closely.
@inducer my bad. I think I confused kernel time and execution time. So, according to your experience, is the kernel time (time cost of set args, enqueue, and execution) of PyOpenCL slower (longer) than C OpenCL?
The Python bits (setting and preparing arguments) is slower, but this time can (and should be) hidden by kernel execution, which occurs asynchronously on the device.
The Python bits (setting and preparing arguments) is slower, but this time can (and should be) hidden by kernel execution, which occurs asynchronously on the device.
I searched online and found that the difference between total_time and execution_time is due to data transfer. What exactly does data transfer mean given that we have already created the buffers.
Is there any way we can reduce this data-transfer time? I have a while loop, in which I execute the above code for thousands of times.
Here is an example code. On my computer, the total time cost is about 0.004 seconds while the execution time cost is 0.0007 seconds. This seems indicating the most of the time is spent on knl.set_args and cl.enqueue_nd_range_kernel. Any idea how to speed up that?
This seems indicating the most of the time is spent on knl.set_args and cl.enqueue_nd_range_kernel. Any idea how to speed up that?
Not really. If you do the following, you'll see that there's a difference even without those.
I'd guess the difference is in the time it takes for the opencl implementation to schedule and run the kernel.
Do you have a equivalent C function that reproduces this?
start = time.time()
execution_time = 0.0
events = []
while index < 100:
knl.set_args(a_g, b_g, res_g)
event = cl.enqueue_nd_range_kernel(queue, knl, a_np.shape, None)
events.append(event)
index += 1
end = time.time()
print(f"total setup cost: {end - start}")
start = time.time()
for event in events:
event.wait()
execution_time += (event.profile.end - event.profile.start) * 1e-9
end = time.time()
print(f"execution time cost: {execution_time}")
print(f"total time cost: {end - start}")
Repository owner locked and limited conversation to collaborators on Sep 16, 2022
Activity
inducer commentedon Jun 28, 2021
PyOpenCL is not involved in the execution of the kernels. The actual on-device kernel execution time should be exactly the same between a C program using OpenCL and a Python program using PyOpenCL. If that's not the case, something is very wrong.
This means that PyOpenCL is a good fit if your code spends most of its time executing kernel code (IMO: as it should!). If the kernel times are so short that kernels complete faster than Python can enqueue them, then there can be a performance impact.
doetools commentedon Jun 28, 2021
@inducer
my application spends most of the time on device (it is called computational fluid dynamics, in case you wonder 😄 ). I only counted the time the kernel is executed. To be specific,
I compiled all my kernels from program and save them into a list
kernels.Interestingly, I got same results between C OpenCL and PyOpenCL. So, I do not think I made any programming mistakes. But I might not use the PyOpenCL in the way it is supposed to.
Could you please comment on which part I should examine my code?
P.S. would it make any difference if i do the following
inducer commentedon Jun 28, 2021
Are you saying your kernel times are different? Switch your command queue to enable profiling and get kernel execution times in both settings. They should match pretty closely.
doetools commentedon Jun 28, 2021
@inducer my bad. I think I confused
kernel timeandexecution time. So, according to your experience, is the kernel time (time cost of set args, enqueue, and execution) of PyOpenCL slower (longer) than C OpenCL?inducer commentedon Jun 28, 2021
The Python bits (setting and preparing arguments) is slower, but this time can (and should be) hidden by kernel execution, which occurs asynchronously on the device.
doetools commentedon Jun 28, 2021
Make sense!
doetools commentedon Jun 28, 2021
@inducer consider the following code
I searched online and found that the difference between
total_timeandexecution_timeis due to data transfer. What exactly does data transfer mean given that we have already created thebuffers.Is there any way we can reduce this data-transfer time? I have a while loop, in which I execute the above code for thousands of times.
Here is an example code. On my computer, the total time cost is about 0.004 seconds while the execution time cost is 0.0007 seconds. This seems indicating the most of the time is spent on
knl.set_argsandcl.enqueue_nd_range_kernel. Any idea how to speed up that?isuruf commentedon Jul 5, 2021
Not really. If you do the following, you'll see that there's a difference even without those.
I'd guess the difference is in the time it takes for the opencl implementation to schedule and run the kernel.
Do you have a equivalent C function that reproduces this?