Back to index

python3.2  3.2.2
Classes | Functions | Variables
ccbench Namespace Reference

Classes

class  TimedLoop

Functions

def task_pidigits
def task_regex
def task_sort
def task_compress_zlib
def task_compress_bz2
def task_hashing
def run_throughput_test
def run_throughput_tests
def _sendto
def _recv
def latency_client
def run_latency_client
def run_latency_test
def run_latency_tests
def bandwidth_client
def run_bandwidth_client
def run_bandwidth_test
def run_bandwidth_tests
def main

Variables

 xrange = range
 map = itertools.imap
float THROUGHPUT_DURATION = 2.0
float LATENCY_PING_INTERVAL = 0.1
float LATENCY_DURATION = 2.0
int BANDWIDTH_PACKET_SIZE = 1024
float BANDWIDTH_DURATION = 2.0
list throughput_tasks = [task_pidigits, task_regex]
 latency_tasks = throughput_tasks
list bandwidth_tasks = [task_pidigits]
string LAT_END = "END"
string BW_END = "END"

Function Documentation

def ccbench._recv (   sock,
  n 
) [private]

Definition at line 275 of file ccbench.py.

00275 
00276 def _recv(sock, n):
00277     return sock.recv(n).decode('ascii')

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench._sendto (   sock,
  s,
  addr 
) [private]

Definition at line 272 of file ccbench.py.

00272 
00273 def _sendto(sock, s, addr):
00274     sock.sendto(s.encode('ascii'), addr)

Here is the caller graph for this function:

def ccbench.bandwidth_client (   addr,
  packet_size,
  duration 
)

Definition at line 406 of file ccbench.py.

00406 
00407 def bandwidth_client(addr, packet_size, duration):
00408     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
00409     sock.bind(("127.0.0.1", 0))
00410     local_addr = sock.getsockname()
00411     _time = time.time
00412     _sleep = time.sleep
00413     def _send_chunk(msg):
00414         _sendto(sock, ("%r#%s\n" % (local_addr, msg)).rjust(packet_size), addr)
00415     # We give the parent some time to be ready.
00416     _sleep(1.0)
00417     try:
00418         start_time = _time()
00419         end_time = start_time + duration * 2.0
00420         i = 0
00421         while _time() < end_time:
00422             _send_chunk(str(i))
00423             s = _recv(sock, packet_size)
00424             assert len(s) == packet_size
00425             i += 1
00426         _send_chunk(BW_END)
00427     finally:
00428         sock.close()

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.latency_client (   addr,
  nb_pings,
  interval 
)

Definition at line 278 of file ccbench.py.

00278 
00279 def latency_client(addr, nb_pings, interval):
00280     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
00281     try:
00282         _time = time.time
00283         _sleep = time.sleep
00284         def _ping():
00285             _sendto(sock, "%r\n" % _time(), addr)
00286         # The first ping signals the parent process that we are ready.
00287         _ping()
00288         # We give the parent a bit of time to notice.
00289         _sleep(1.0)
00290         for i in range(nb_pings):
00291             _sleep(interval)
00292             _ping()
00293         _sendto(sock, LAT_END + "\n", addr)
00294     finally:
00295         sock.close()

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.main ( void  )

Definition at line 531 of file ccbench.py.

00531 
00532 def main():
00533     usage = "usage: %prog [-h|--help] [options]"
00534     parser = OptionParser(usage=usage)
00535     parser.add_option("-t", "--throughput",
00536                       action="store_true", dest="throughput", default=False,
00537                       help="run throughput tests")
00538     parser.add_option("-l", "--latency",
00539                       action="store_true", dest="latency", default=False,
00540                       help="run latency tests")
00541     parser.add_option("-b", "--bandwidth",
00542                       action="store_true", dest="bandwidth", default=False,
00543                       help="run I/O bandwidth tests")
00544     parser.add_option("-i", "--interval",
00545                       action="store", type="int", dest="check_interval", default=None,
00546                       help="sys.setcheckinterval() value")
00547     parser.add_option("-I", "--switch-interval",
00548                       action="store", type="float", dest="switch_interval", default=None,
00549                       help="sys.setswitchinterval() value")
00550     parser.add_option("-n", "--num-threads",
00551                       action="store", type="int", dest="nthreads", default=4,
00552                       help="max number of threads in tests")
00553 
00554     # Hidden option to run the pinging and bandwidth clients
00555     parser.add_option("", "--latclient",
00556                       action="store", dest="latclient", default=None,
00557                       help=SUPPRESS_HELP)
00558     parser.add_option("", "--bwclient",
00559                       action="store", dest="bwclient", default=None,
00560                       help=SUPPRESS_HELP)
00561 
00562     options, args = parser.parse_args()
00563     if args:
00564         parser.error("unexpected arguments")
00565 
00566     if options.latclient:
00567         kwargs = eval(options.latclient)
00568         latency_client(**kwargs)
00569         return
00570 
00571     if options.bwclient:
00572         kwargs = eval(options.bwclient)
00573         bandwidth_client(**kwargs)
00574         return
00575 
00576     if not options.throughput and not options.latency and not options.bandwidth:
00577         options.throughput = options.latency = options.bandwidth = True
00578     if options.check_interval:
00579         sys.setcheckinterval(options.check_interval)
00580     if options.switch_interval:
00581         sys.setswitchinterval(options.switch_interval)
00582 
00583     print("== %s %s (%s) ==" % (
00584         platform.python_implementation(),
00585         platform.python_version(),
00586         platform.python_build()[0],
00587     ))
00588     # Processor identification often has repeated spaces
00589     cpu = ' '.join(platform.processor().split())
00590     print("== %s %s on '%s' ==" % (
00591         platform.machine(),
00592         platform.system(),
00593         cpu,
00594     ))
00595     print()
00596 
00597     if options.throughput:
00598         print("--- Throughput ---")
00599         print()
00600         run_throughput_tests(options.nthreads)
00601 
00602     if options.latency:
00603         print("--- Latency ---")
00604         print()
00605         run_latency_tests(options.nthreads)
00606 
00607     if options.bandwidth:
00608         print("--- I/O bandwidth ---")
00609         print()
00610         run_bandwidth_tests(options.nthreads)

Here is the call graph for this function:

def ccbench.run_bandwidth_client (   kwargs)

Definition at line 429 of file ccbench.py.

00429 
00430 def run_bandwidth_client(**kwargs):
00431     cmd_line = [sys.executable, '-E', os.path.abspath(__file__)]
00432     cmd_line.extend(['--bwclient', repr(kwargs)])
00433     return subprocess.Popen(cmd_line) #, stdin=subprocess.PIPE,
00434                             #stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Here is the caller graph for this function:

def ccbench.run_bandwidth_test (   func,
  args,
  nthreads 
)

Definition at line 435 of file ccbench.py.

00435 
00436 def run_bandwidth_test(func, args, nthreads):
00437     # Create a listening socket to receive the packets. We use UDP which should
00438     # be painlessly cross-platform.
00439     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
00440     sock.bind(("127.0.0.1", 0))
00441     addr = sock.getsockname()
00442 
00443     duration = BANDWIDTH_DURATION
00444     packet_size = BANDWIDTH_PACKET_SIZE
00445 
00446     results = []
00447     threads = []
00448     end_event = []
00449     start_cond = threading.Condition()
00450     started = False
00451     if nthreads > 0:
00452         # Warm up
00453         func(*args)
00454 
00455         results = []
00456         loop = TimedLoop(func, args)
00457         ready = []
00458         ready_cond = threading.Condition()
00459 
00460         def run():
00461             with ready_cond:
00462                 ready.append(None)
00463                 ready_cond.notify()
00464             with start_cond:
00465                 while not started:
00466                     start_cond.wait()
00467             loop(start_time, duration * 1.5, end_event, do_yield=False)
00468 
00469         for i in range(nthreads):
00470             threads.append(threading.Thread(target=run))
00471         for t in threads:
00472             t.setDaemon(True)
00473             t.start()
00474         # Wait for threads to be ready
00475         with ready_cond:
00476             while len(ready) < nthreads:
00477                 ready_cond.wait()
00478 
00479     # Run the client and wait for the first packet to arrive before
00480     # unblocking the background threads.
00481     process = run_bandwidth_client(addr=addr,
00482                                    packet_size=packet_size,
00483                                    duration=duration)
00484     _time = time.time
00485     # This will also wait for the parent to be ready
00486     s = _recv(sock, packet_size)
00487     remote_addr = eval(s.partition('#')[0])
00488 
00489     with start_cond:
00490         start_time = _time()
00491         started = True
00492         start_cond.notify(nthreads)
00493 
00494     n = 0
00495     first_time = None
00496     while not end_event and BW_END not in s:
00497         _sendto(sock, s, remote_addr)
00498         s = _recv(sock, packet_size)
00499         if first_time is None:
00500             first_time = _time()
00501         n += 1
00502     end_time = _time()
00503 
00504     end_event.append(None)
00505     for t in threads:
00506         t.join()
00507     process.kill()
00508 
00509     return (n - 1) / (end_time - first_time)

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.run_bandwidth_tests (   max_threads)

Definition at line 510 of file ccbench.py.

00510 
00511 def run_bandwidth_tests(max_threads):
00512     for task in bandwidth_tasks:
00513         print("Background CPU task:", task.__doc__)
00514         print()
00515         func, args = task()
00516         nthreads = 0
00517         baseline_speed = None
00518         while nthreads <= max_threads:
00519             results = run_bandwidth_test(func, args, nthreads)
00520             speed = results
00521             #speed = len(results) * 1.0 / results[-1][0]
00522             print("CPU threads=%d: %.1f" % (nthreads, speed), end="")
00523             if baseline_speed is None:
00524                 print(" packets/s.")
00525                 baseline_speed = speed
00526             else:
00527                 print(" ( %d %%)" % (speed / baseline_speed * 100))
00528             nthreads += 1
00529         print()
00530 

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.run_latency_client (   kwargs)

Definition at line 296 of file ccbench.py.

00296 
00297 def run_latency_client(**kwargs):
00298     cmd_line = [sys.executable, '-E', os.path.abspath(__file__)]
00299     cmd_line.extend(['--latclient', repr(kwargs)])
00300     return subprocess.Popen(cmd_line) #, stdin=subprocess.PIPE,
00301                             #stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Here is the caller graph for this function:

def ccbench.run_latency_test (   func,
  args,
  nthreads 
)

Definition at line 302 of file ccbench.py.

00302 
00303 def run_latency_test(func, args, nthreads):
00304     # Create a listening socket to receive the pings. We use UDP which should
00305     # be painlessly cross-platform.
00306     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
00307     sock.bind(("127.0.0.1", 0))
00308     addr = sock.getsockname()
00309 
00310     interval = LATENCY_PING_INTERVAL
00311     duration = LATENCY_DURATION
00312     nb_pings = int(duration / interval)
00313 
00314     results = []
00315     threads = []
00316     end_event = []
00317     start_cond = threading.Condition()
00318     started = False
00319     if nthreads > 0:
00320         # Warm up
00321         func(*args)
00322 
00323         results = []
00324         loop = TimedLoop(func, args)
00325         ready = []
00326         ready_cond = threading.Condition()
00327 
00328         def run():
00329             with ready_cond:
00330                 ready.append(None)
00331                 ready_cond.notify()
00332             with start_cond:
00333                 while not started:
00334                     start_cond.wait()
00335             loop(start_time, duration * 1.5, end_event, do_yield=False)
00336 
00337         for i in range(nthreads):
00338             threads.append(threading.Thread(target=run))
00339         for t in threads:
00340             t.setDaemon(True)
00341             t.start()
00342         # Wait for threads to be ready
00343         with ready_cond:
00344             while len(ready) < nthreads:
00345                 ready_cond.wait()
00346 
00347     # Run the client and wait for the first ping(s) to arrive before
00348     # unblocking the background threads.
00349     chunks = []
00350     process = run_latency_client(addr=sock.getsockname(),
00351                                  nb_pings=nb_pings, interval=interval)
00352     s = _recv(sock, 4096)
00353     _time = time.time
00354 
00355     with start_cond:
00356         start_time = _time()
00357         started = True
00358         start_cond.notify(nthreads)
00359 
00360     while LAT_END not in s:
00361         s = _recv(sock, 4096)
00362         t = _time()
00363         chunks.append((t, s))
00364 
00365     # Tell the background threads to stop.
00366     end_event.append(None)
00367     for t in threads:
00368         t.join()
00369     process.wait()
00370     sock.close()
00371 
00372     for recv_time, chunk in chunks:
00373         # NOTE: it is assumed that a line sent by a client wasn't received
00374         # in two chunks because the lines are very small.
00375         for line in chunk.splitlines():
00376             line = line.strip()
00377             if line and line != LAT_END:
00378                 send_time = eval(line)
00379                 assert isinstance(send_time, float)
00380                 results.append((send_time, recv_time))
00381 
00382     return results

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.run_latency_tests (   max_threads)

Definition at line 383 of file ccbench.py.

00383 
00384 def run_latency_tests(max_threads):
00385     for task in latency_tasks:
00386         print("Background CPU task:", task.__doc__)
00387         print()
00388         func, args = task()
00389         nthreads = 0
00390         while nthreads <= max_threads:
00391             results = run_latency_test(func, args, nthreads)
00392             n = len(results)
00393             # We print out milliseconds
00394             lats = [1000 * (t2 - t1) for (t1, t2) in results]
00395             #print(list(map(int, lats)))
00396             avg = sum(lats) / n
00397             dev = (sum((x - avg) ** 2 for x in lats) / n) ** 0.5
00398             print("CPU threads=%d: %d ms. (std dev: %d ms.)" % (nthreads, avg, dev), end="")
00399             print()
00400             #print("    [... from %d samples]" % n)
00401             nthreads += 1
00402         print()
00403 

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.run_throughput_test (   func,
  args,
  nthreads 
)

Definition at line 195 of file ccbench.py.

00195 
00196 def run_throughput_test(func, args, nthreads):
00197     assert nthreads >= 1
00198 
00199     # Warm up
00200     func(*args)
00201 
00202     results = []
00203     loop = TimedLoop(func, args)
00204     end_event = []
00205 
00206     if nthreads == 1:
00207         # Pure single-threaded performance, without any switching or
00208         # synchronization overhead.
00209         start_time = time.time()
00210         results.append(loop(start_time, THROUGHPUT_DURATION,
00211                             end_event, do_yield=False))
00212         return results
00213 
00214     started = False
00215     ready_cond = threading.Condition()
00216     start_cond = threading.Condition()
00217     ready = []
00218 
00219     def run():
00220         with ready_cond:
00221             ready.append(None)
00222             ready_cond.notify()
00223         with start_cond:
00224             while not started:
00225                 start_cond.wait()
00226         results.append(loop(start_time, THROUGHPUT_DURATION,
00227                             end_event, do_yield=True))
00228 
00229     threads = []
00230     for i in range(nthreads):
00231         threads.append(threading.Thread(target=run))
00232     for t in threads:
00233         t.setDaemon(True)
00234         t.start()
00235     # We don't want measurements to include thread startup overhead,
00236     # so we arrange for timing to start after all threads are ready.
00237     with ready_cond:
00238         while len(ready) < nthreads:
00239             ready_cond.wait()
00240     with start_cond:
00241         start_time = time.time()
00242         started = True
00243         start_cond.notify(nthreads)
00244     for t in threads:
00245         t.join()
00246 
00247     return results

Here is the call graph for this function:

Here is the caller graph for this function:

def ccbench.run_throughput_tests (   max_threads)

Definition at line 248 of file ccbench.py.

00248 
00249 def run_throughput_tests(max_threads):
00250     for task in throughput_tasks:
00251         print(task.__doc__)
00252         print()
00253         func, args = task()
00254         nthreads = 1
00255         baseline_speed = None
00256         while nthreads <= max_threads:
00257             results = run_throughput_test(func, args, nthreads)
00258             # Taking the max duration rather than average gives pessimistic
00259             # results rather than optimistic.
00260             speed = sum(r[0] for r in results) / max(r[1] for r in results)
00261             print("threads=%d: %d" % (nthreads, speed), end="")
00262             if baseline_speed is None:
00263                 print(" iterations/s.")
00264                 baseline_speed = speed
00265             else:
00266                 print(" ( %d %%)" % (speed / baseline_speed * 100))
00267             nthreads += 1
00268         print()
00269 

Here is the call graph for this function:

Here is the caller graph for this function:

bz2 compression (C)

Definition at line 115 of file ccbench.py.

00115 
00116 def task_compress_bz2():
00117     """bz2 compression (C)"""
00118     import bz2
00119     with open(__file__, "rb") as f:
00120         arg = f.read(3000) * 2
00121 
00122     def compress(s):
00123         bz2.compress(s)
00124     return compress, (arg, )

Here is the call graph for this function:

zlib compression (C)

Definition at line 105 of file ccbench.py.

00105 
00106 def task_compress_zlib():
00107     """zlib compression (C)"""
00108     import zlib
00109     with open(__file__, "rb") as f:
00110         arg = f.read(5000) * 3
00111 
00112     def compress(s):
00113         zlib.decompress(zlib.compress(s, 5))
00114     return compress, (arg, )

Here is the call graph for this function:

SHA1 hashing (C)

Definition at line 125 of file ccbench.py.

00125 
00126 def task_hashing():
00127     """SHA1 hashing (C)"""
00128     import hashlib
00129     with open(__file__, "rb") as f:
00130         arg = f.read(5000) * 30
00131 
00132     def compute(s):
00133         hashlib.sha1(s).digest()
00134     return compute, (arg, )
00135 

Pi calculation (Python)

Definition at line 42 of file ccbench.py.

00042 
00043 def task_pidigits():
00044     """Pi calculation (Python)"""
00045     _map = map
00046     _count = itertools.count
00047     _islice = itertools.islice
00048 
00049     def calc_ndigits(n):
00050         # From http://shootout.alioth.debian.org/
00051         def gen_x():
00052             return _map(lambda k: (k, 4*k + 2, 0, 2*k + 1), _count(1))
00053 
00054         def compose(a, b):
00055             aq, ar, as_, at = a
00056             bq, br, bs, bt = b
00057             return (aq * bq,
00058                     aq * br + ar * bt,
00059                     as_ * bq + at * bs,
00060                     as_ * br + at * bt)
00061 
00062         def extract(z, j):
00063             q, r, s, t = z
00064             return (q*j + r) // (s*j + t)
00065 
00066         def pi_digits():
00067             z = (1, 0, 0, 1)
00068             x = gen_x()
00069             while 1:
00070                 y = extract(z, 3)
00071                 while y != extract(z, 4):
00072                     z = compose(z, next(x))
00073                     y = extract(z, 3)
00074                 z = compose((10, -10*y, 0, 1), z)
00075                 yield y
00076 
00077         return list(_islice(pi_digits(), n))
00078 
00079     return calc_ndigits, (50, )

regular expression (C)

Definition at line 80 of file ccbench.py.

00080 
00081 def task_regex():
00082     """regular expression (C)"""
00083     # XXX this task gives horrendous latency results.
00084     import re
00085     # Taken from the `inspect` module
00086     pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)', re.MULTILINE)
00087     with open(__file__, "r") as f:
00088         arg = f.read(2000)
00089 
00090     def findall(s):
00091         t = time.time()
00092         try:
00093             return pat.findall(s)
00094         finally:
00095             print(time.time() - t)
00096     return pat.findall, (arg, )

Here is the call graph for this function:

list sorting (C)

Definition at line 97 of file ccbench.py.

00097 
00098 def task_sort():
00099     """list sorting (C)"""
00100     def list_sort(l):
00101         l = l[::-1]
00102         l.sort()
00103 
00104     return list_sort, (list(range(1000)), )


Variable Documentation

Definition at line 39 of file ccbench.py.

Definition at line 38 of file ccbench.py.

Definition at line 154 of file ccbench.py.

Definition at line 404 of file ccbench.py.

Definition at line 270 of file ccbench.py.

Definition at line 36 of file ccbench.py.

Definition at line 35 of file ccbench.py.

Definition at line 153 of file ccbench.py.

ccbench.map = itertools.imap

Definition at line 28 of file ccbench.py.

Definition at line 33 of file ccbench.py.

Definition at line 136 of file ccbench.py.

ccbench.xrange = range

Definition at line 25 of file ccbench.py.