I wish to calculate runtime of my program which approximates PI using Monte Carlo Method. I have written a unix shell script which feeds the program No of points, N = 10^{k} , for K = 1,2, ...7.
Now I wish to find the execution time for Each N in Unix program time. My unix shell script looks as follows:
#!/bin/bash
k=1
N=10
while [[ k -le 7 ]]
do
echo "$k N" | ./pi $N
((k = k + 1))
((N = N * 10))
done
Now when I type: $ time ./pi.sh , it returns me the total execution time
10 3.6 0.1459155902616465
100 3.08 0.01960555055392467
1000 3.104 0.01196611328551369
10000 3.1284 0.004199352062629202
100000 3.1432 0.0005116342528909465
1000000 3.139704 0.0006011771092076384
10000000 3.141432 5.113762588206346e-05
real 0m0.583s
user 0m0.560s
sys 0m0.012s
I was wondering if I have to write a bash script to get execution time for Each N input or I have to do something in my code.
By writing $ time ./pi.sh you are measuring time needed to execute pi.sh, which has a loop in it. So you measure total time for all iterations. If you want to measure every iteration independently, you have to put time in invocation of the iteration:
echo "$k N" | time ./pi $N
Related
I need to calculate the total amount of time for a certain number of tasks to be completed. Details:
5 tasks total. Time estimates (in seconds) for each: [30, 10, 15, 20, 25]
Concurrency: 3 tasks at a time
How can I calculate the total time it will take to process all tasks, given the concurrency? I know it will take at least as long as the longest task (25 seconds), but is there a formula/method to calculate a rough total estimate, that will scale with more tasks added?
If you don't mind making some approximations it could be quite simple. If the tasks take roughly the same time to complete, you could use the average of the tasks duration as a basis (here, 20 seconds).
Assuming that the system is always full of tasks, that task duration is small enough, that there are many tasks and that concurrency level is high enough, then:
estimated_duration = average_task_duration * nb_tasks / nb_workers
Where nb_workers is the number of concurrent threads.
Here is some Python code that shows the idea:
from random import random
from time import sleep, monotonic
from concurrent.futures import ThreadPoolExecutor
def task(i: int, duration: float):
sleep(duration)
def main():
nb_tasks = 20
nb_workers = 3
average_task_duration = 2.0
expected_duration = nb_tasks * average_task_duration / nb_workers
durations = [average_task_duration + (random() - 0.5) for _ in range(nb_tasks)]
print(f"Starting work... Expected duration: {expected_duration:.2f} s")
start = monotonic()
with ThreadPoolExecutor(max_workers=nb_workers) as executor:
for i, d in enumerate(durations):
executor.submit(task, i, d)
stop = monotonic()
print(f"Elapsed: {(stop - start):.2f} s")
if __name__ == "__main__":
main()
If these hypotheses cannot hold in your case, then you'd better use a Bin Packing algorithm as Jerôme suggested.
I am developing a python application using Python2.7.
That application is using pyserial library to read some data bytes from serial port.
Using while loop to read 1 byte of data in each iteration. In each iteration
I have to measure execution time between statements if it is less than 10 ms wait for it to reach 10ms before starting next iteration. there are two questions here as follows:
Time measurement
What would be the best way to measure time between python statements to the accuracy (1ms or 2ms difference acceptable) of milliseconds.
Time delay
How can i use that measured time for delay in order to wait till total time is 10ms (total time = 10ms = code execution time+delay)
I have tried time library but it does not give a good resolution when in millisecond some time it does not give anything when small time duration.
for example:
import time
while uart.is_open:
uart.read()
start = time.time()
#user code will go here
end = time.time()
execution_time=end - start
if execution_time< 10ms:
remaining_time = 10ms - execution_time
delay(remaining_time)
You can get a string that is minutes:seconds:microseconds using datetime like so:
import datetime
string = datetime.datetime.now().strftime("%M:%S:%f")
And then turn it into a number to make comparison more handy:
m, s, u = string.split(":")
time_us = float(m)/60e6 + float(s)/1e6 + float(u)
In your example, that would look like this:
import datetime
def time_us_now():
h, m, s, u = (float(string) for string in datetime.datetime.now().strftime("%H:%M:%S:%f").split(":"))
return h/3600e6 + m/60e6 + s/1e6 + u
start = time_us_now()
# User code will go here.
end = time_us_now()
execution_time = end - start
Solution:
I have managed to get upto 1ms resolution by doing two things.
Changed (increased) the baud rate to 115200 from 19200.
Used time.clock() rather than time.time() as it has more accuracy and resolution.
My ini code for the config is as:
[Config BR54MBPS1MS]
description = "at 54MBPS with SI 1ms for 1250 Bytes with all time interval"
repeat = 2
sim-time-limit = 1 min
**.scalar-recording = true
**.vector-recording = false
**.host1.udpApp[0].messageLength = 1250B
**.wlan*.bitrate = 54Mbps
**.host1.udpApp[*].sendInterval = ${interval = 100..1200 step 100} us
**.vector-recording = false
output-scalar-file = 54Mbps/${configname}54Mbps${interval}us.sca
and I want to run it for all given intervals from 100 us to 1200 us with a gap of 100 us (at 100, 200, 300 ... us) in omnet tkenv or gui. The only option I read for it is by run it through run configuration as:
The problem is that, it runs only for 100us successfully, generates the output sca file and terminates the process. I am not able to figure out the reason for not running the for the next send interval.
In order to run all combinations of sendInterval values you should write * (asterisk) in Run number field and select Command line interface. Multiple runs are not possible when Tcl/Tk user interface is selected.
I am trying to read though a list and I want to read 25 at a time in the list then sleep for 5 seconds then keep reading 25 at a time until I exhaust the list.
This is what I'm doing right now, but I start too many ssh sessions at the same time. I want to be able to run 25, sleep for 5 seconds, run 25 more until the list has been exhausted.
cat ctrlnodes.txt |\
while read N
do
ssh -n $N "/var/opt/OV/bin/instrumentation/agent_health.sh" &
done
Answer
counter=0
while read N; do
((counter++))
ssh -n $N "/var/opt/OV/bin/instrumentation/agent_health.sh" &
[[ $(($counter % 25)) = 0 ]] && sleep 5
done <ctrlnodes.txt
Explanation
First, a counter needs to be initialized before the loop and incremented through each iteration; this allows the script to test whether it's on an iteration that's evenly divisible by 25.
Second, you need to change the cat pipe of your text file to while to a direct input redirection on done; when you use the former a subshell is created and $counter will be out of scope and won't increment properly.
Finally, what probably needs the most explanation is the evenly-divisible test itself:
[[ $(($counter % 25)) = 0 ]] && sleep 5
What this does is perform a test of whether modulus 25 of the counter is zero. (i.e., $counter is evenly divisible by 25) If it is then the test's exit value is true, so the 'and' (&&) can continue on to the sleep command; if the modulus value is non-zero then the && won't continue since the test will have a false exit value.
A one-liner test of the concept:
seq 1 100 >numbers.txt && counter=0 && while read N; do ((counter++)); echo $N; [[ $(($counter % 25)) = 0 ]] && echo -n sleeping... && sleep 5 && echo; done <numbers.txt
What you should see is blocks of 25 numbers, a "sleeping..." line with a 5 second pause, until it's gone through all 1..100.
for i in $(seq 1 100 )
do
for j in $(seq 1 25)
do
# suppose you have an array
echo ${your_list[i]}
done
sleep 5
done
Lets create a file with one integer/row, 100 rows:
$ seq 1 100 > data
Using the script below:
#!/bin/bash
n=1
while read N
do
# here you call your ssh
if [ $((n % 25)) -eq 0 ]
then
echo "Spawned 25 subprocesses, waiting..."
echo $n, $N
# wait for all subprocesses to finish before continuing
# Replace 'wait' with 'sleep 5' if that's desired
wait
fi
((n+=1))
done < data
output:
$ ./s.sh
Spawned 25 subprocesses, waiting...
25, 25
Spawned 25 subprocesses, waiting...
50, 50
Spawned 25 subprocesses, waiting...
75, 75
Spawned 25 subprocesses, waiting...
100, 100
Hi all is there a way we can show progress bar for 10 minutes with statistics of percentage completed how much time remaining for 10 Minutes? using Write-Progress.
If I understand the question correctly the goal is to show some additional
information in the progress messages. This can be done for example by using the
Activity parameter. The script below only shows the idea (for 1 minute, for a
shorter test). It should be modified in order to reflect actually needed format
of the message and information to be shown.
$time = 60 # seconds, use you actual time in here
foreach($i in (1..$time)) {
$percentage = $i / $time
$remaining = New-TimeSpan -Seconds ($time - $i)
$message = "{0:p0} complete, remaining time {1}" -f $percentage, $remaining
Write-Progress -Activity $message -PercentComplete ($percentage * 100)
Start-Sleep 1
}
The progress looks like this:
57 % complete, remaining time 00:00:26
Processing
[oooooooooooooooooooooooooooooooooooooooooooooooooooooo