Nir Soffer has uploaded a new change for review.
Change subject: sampling: Add sampling benchmark for profiling
......................................................................
sampling: Add sampling benchmark for profiling
We have trouble profiling vdsm when using 100's of vms. This patch adds
simple benchmark, simulating vdsm sampling, for evaluating the sampling
implementation.
Change-Id: I7bbb73f38fbbbdfc1fe7050ac3e30327411f8f33
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
A tests/perf/sampling_perf.py
1 file changed, 131 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/87/30987/1
diff --git a/tests/perf/sampling_perf.py b/tests/perf/sampling_perf.py
new file mode 100644
index 0000000..f656474
--- /dev/null
+++ b/tests/perf/sampling_perf.py
@@ -0,0 +1,131 @@
+# Compare sampling in multiple threads vs sampling via the scheduler and
+# executor.
+
+import pthreading
+pthreading.monkey_patch()
+
+import sys
+sys.path = ['../../lib', '../../vdsm'] + sys.path
+
+import libvirt
+import logging
+import signal
+import threading
+import time
+from xml.dom import minidom
+
+from vdsm import executor as execute
+from vdsm import profile
+from vdsm import schedule
+from vdsm import utils
+
+from virt import sampling
+
+RUN_SEC = 120
+VMS = 100
+
+connection = libvirt.openReadOnly('qemu:///system')
+
+
+def sampling_task():
+ # Do some libvirt calls and do some xml processing, simulating vdsm
+ # sampling functions.
+ sp = connection.listAllStoragePools()[0]
+ xml = sp.XMLDesc()
+ dom = minidom.parseString(xml)
+ uuid = dom.getElementsByTagName('uuid')[0]
+ return uuid.childNodes[0].data
+
+
+samplings = (
+ sampling.AdvancedStatsFunction(sampling_task, 2), # highWrite
+ sampling.AdvancedStatsFunction(sampling_task, 15), # sampleVmJobs
+ sampling.AdvancedStatsFunction(sampling_task, 15), # sampleBalloon
+ sampling.AdvancedStatsFunction(sampling_task, 15), # sampleCpu
+ sampling.AdvancedStatsFunction(sampling_task, 15), # sampleNet
+ sampling.AdvancedStatsFunction(sampling_task, 15), # sampleVcpuPinning
+ sampling.AdvancedStatsFunction(sampling_task, 15), # sampleCpuTune
+ sampling.AdvancedStatsFunction(sampling_task, 60), # updateVolumes
+ sampling.AdvancedStatsFunction(sampling_task, 60), # sampleDisk
+ sampling.AdvancedStatsFunction(sampling_task, 60), # sampleDiskLatency
+)
+
+
+class SamplerThread(object):
+
+ def __init__(self, name, samplings):
+ self.iterator = sampling.delays(sampling.cycle(samplings))
+ self.thread = threading.Thread(target=self._run, name=name)
+ self.thread.daemon = True
+ self.event = threading.Event()
+ self.last_sample_time = 0
+
+ def start(self):
+ logging.debug("starting %s", self.thread.name)
+ self.thread.start()
+
+ def stop(self):
+ logging.debug("stopping %s", self.thread.name)
+ self.event.set()
+
+ @utils.traceback()
+ def _run(self):
+ logging.debug("%s started", self.thread.name)
+ while not self.event.is_set():
+ delay, task = next(self.iterator)
+ if delay > 0:
+ self.event.wait(delay)
+ if self.event.is_set():
+ break
+ self.last_sample_time = time.time()
+ task()
+ logging.debug("%s stopped", self.thread.name)
+
+
+(a)profile.profile("threads.prof", builtins=True)
+def do_threads(vms):
+ threads = []
+ try:
+ for i in range(vms):
+ t = SamplerThread('SamplerThread-%i' % i, samplings)
+ t.start()
+ threads.append(t)
+ time.sleep(RUN_SEC)
+ finally:
+ for t in threads:
+ t.stop()
+
+
+(a)profile.profile("pool.prof", builtins=True)
+def do_pool(vms):
+ scheduler = schedule.Scheduler()
+ scheduler.start()
+ executor = execute.Executor(5, 1000, scheduler)
+ executor.start()
+ samplers = []
+ try:
+ for i in range(vms):
+ s = sampling.Sampler("Sampler-%i" % i, samplings, None,
+ scheduler=scheduler, executor=executor)
+ s.start()
+ samplers.append(s)
+ time.sleep(RUN_SEC)
+ finally:
+ for s in samplers:
+ s.stop()
+ executor.stop()
+ scheduler.stop()
+
+
+if __name__ == '__main__':
+ logging.basicConfig(level=logging.DEBUG)
+ if len(sys.argv) == 1:
+ print 'Usage: pyhton sampling_perf.py threads|pool [vms]'
+ sys.exit(2)
+ name = 'do_' + sys.argv[1]
+ func = globals()[name]
+ if len(sys.argv) > 2:
+ vms = int(sys.argv[2])
+ else:
+ vms = VMS
+ func(vms)
--
To view, visit
http://gerrit.ovirt.org/30987
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7bbb73f38fbbbdfc1fe7050ac3e30327411f8f33
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>