I have a code written in Python that takes about 9% of the CPU when ran. I want it to use more so it can run faster. To solve this problem, I tried multiprocessing, however, before writing a code for it, I ran the same program in two different terminal which created two different Python processes. However, instead of each taking 9% of the CPU for a total of about 18% of CPU, each take about 5% for a total of 10% CPU. How can I change that and have each process take 9% of CPU or have just one program take>20% of CPU?
Thank you!
import spidev, time, os
# opens SPI bus
spi = spidev.SpiDev()
spi.open(0, 0)
#spi1 = spidev.SpiDev()
#spi1.open(0, 1)
ch0 = 0
#ch1 = 1
now = time.time() * 1000
data = open("test_plot.dat", "w")
#data1 = open("test_plot_1.dat", "w")
def getReading(channel):
# pull raw data from chip
rawData = spi.xfer([1, (8 + channel) << 4, 0])
# process raw data to something we understand
processedData = ((rawData[1]&3) << 8) + rawData[2]
return processedData
"""
def getReading1(channel):
# pull raw data from chip
rawData = spi1.xfer([1, (8 + channel) << 4, 0])
# process raw data to something we understand
processedData = ((rawData[1]&3) << 8) + rawData[2]
return processedData
"""
while True:
if (((time.time() * 1000) - now) < 10001):
data.write("%d\n" % getReading(ch0))
#data1.write("%d\n" % getReading1(ch1))
else:
break
# http://www.takaitra.com/posts/492
1 Answer 1
You have two bottlenecks here that are going to slow you down. First, there's the SPI, which was mentioned in a comment. That takes a few clock cycles in each direction and will limit you some. The second is writing to the SD card. I expect that the second is more important for your speed. Disk writes are generally much slower than computations, and the SD card is even slower than disk.
If you just want to use the whole number of CPU cycles, try taking those out and see what happens. Of course that means you won't be accomplishing your task, so then you'll need to put them back in some other way. A possible option would be to buffer your write-to-disk operations and have them trickle out in their own thread while the rest of the code runs. This may or may not work - For example, you might over-run the buffer and crash. You'll have to do some design and experimentation.
-
Is there any way of reducing those clock cycles? MCP3008's datasheet mentions that it takes about 24 clock cycles per sample. I suspect that even if I can reduce it to about 20 cycles per sample, I should be able to increase the speed substantially. So, how exactly do I write to buffer and then to disk? Any tutorials or something? Will creating a list of all the input and then writing it to a file once I am done with my data collection do the trick?Always Learning Forever– Always Learning Forever2017年07月26日 01:21:31 +00:00Commented Jul 26, 2017 at 1:21
-
@Akshat Tripathi, what is your real objective? You seem focused on increasing CPU usage but I suspect that's the wrong metric for what you really want to do. Are you really trying to increase your sample rate?Daddy the Runner– Daddy the Runner2017年07月26日 10:06:46 +00:00Commented Jul 26, 2017 at 10:06
-
Yes, that's exactly what I am trying to do. I want to get as many sample points per second as possible. Ideally, 200k samples/second with this ADCPi3-user-here– Pi3-user-here2017年07月26日 15:12:30 +00:00Commented Jul 26, 2017 at 15:12
-
@AkshatTripathi I don't believe that you can reduce the cycles for the samples via SPI. The protocol works by sending a series of rising and falling edges over the line, and that necessarily takes clock cycles. The only option that I see is to use multiple SPI buses in parallel on different threads / processes, but there's a limit on the number of buses that you can have on the Pi. Moreover, you'll need to understand how to design and write the parallel program, which may or may not be an issue for you. Python does have "multiprocessing" but it does NOT have multi-threading, just FYI.Brick– Brick2017年07月26日 16:21:38 +00:00Commented Jul 26, 2017 at 16:21
-
1Profiling before optimizing existing code is always good advice. For new design, you'll have to relay on understanding of principals as a guide. Regarding language, you should match what you use to the job. Personally I avoid Python unless there's a specific open source module that I want to use and cannot find in a better language. For low level data connects, I'd go to C/C++. Java's sometimes handy due to its relatively user-friendly threading model. I have tools in place that let me easily use all of the above in a single program. If you want a simple yes/no, however, I'd say yes to C here.Brick– Brick2017年07月28日 14:52:55 +00:00Commented Jul 28, 2017 at 14:52
GetReading
will block the process until its complete so 99.99999% of this script is just waiting for IO.