{"thread":{"id":"27547","subject":"[PATCH] Profile feedback based optimization","startedAt":"2011-06-04T15:38:21Z","lastAt":"2011-06-04T15:38:21Z","messageCount":1,"participants":["Cesar Eduardo Barros"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"169302","messageId":"1307201901-8298-1-git-send-email-cesarb@cesarb.net","threadId":"27547","inReplyTo":null,"subject":"[PATCH] Profile feedback based optimization","fromName":"Cesar Eduardo Barros","fromEmail":"cesarb@cesarb.net","sentAt":"2011-06-04T15:38:21Z","receivedAt":"2011-06-04T15:38:21Z","isPatch":true,"sender":{"key":"cesarb@cesarb.net","avatar":"https://avatars.githubusercontent.com/u/31324?v=4"},"body":"gcc has options to instrument the generated executable and use the\ncollected information to better optimize the generated code.\n\nTo use the profile feedback options, you have to compile twice. After\nthe first compilation, you have to run the executable with a\nrepresentative set of data to generate the statistics for the second\ncompilation.\n\nA benchmark was chosen as the representative set of data because a\nbenchmark focuses on measuring the code speed. A good benchmark should\nbe designed considering how git is commonly used, emphasizing the most\nused parts, but without neglecting the less used parts.\n\nTo simplify the patch and focus on the Makefile rules, a dummy benchmark\nwas used, which does only a few simple operations a hundred times.\n\nEven with just that simple benchmark, it seems to already have some\neffect. These were the results of a test run of \"./git fsck --full\" on\nthe git repository, recorded via perf stat, ran twice without profile\nfeedback and then twice with profile feedback:\n\nWithout profile feedback:\n\n Performance counter stats for './git fsck --full':\n\n       84159,595732  task-clock-msecs         #      0,998 CPUs\n               8470  context-switches         #      0,000 M/sec\n                  7  CPU-migrations           #      0,000 M/sec\n             263682  page-faults              #      0,003 M/sec\n       179028259343  cycles                   #   2127,247 M/sec\n       222624952497  instructions             #      1,244 IPC\n        22651880335  branches                 #    269,154 M/sec\n         1798298585  branch-misses            #      7,939 %\n         1380706193  cache-references         #     16,406 M/sec\n          588704688  cache-misses             #      6,995 M/sec\n\n       84,360035244  seconds time elapsed\n\n Performance counter stats for './git fsck --full':\n\n       84207,836012  task-clock-msecs         #      0,998 CPUs\n               8450  context-switches         #      0,000 M/sec\n                  2  CPU-migrations           #      0,000 M/sec\n             211878  page-faults              #      0,003 M/sec\n       179131407549  cycles                   #   2127,253 M/sec\n       222395625483  instructions             #      1,242 IPC\n        22614432765  branches                 #    268,555 M/sec\n         1798786420  branch-misses            #      7,954 %\n         1384878082  cache-references         #     16,446 M/sec\n          594115144  cache-misses             #      7,055 M/sec\n\n       84,404733868  seconds time elapsed\n\nWith profile feedback:\n\n Performance counter stats for './git fsck --full':\n\n       83576,534090  task-clock-msecs         #      0,998 CPUs\n               8610  context-switches         #      0,000 M/sec\n                 10  CPU-migrations           #      0,000 M/sec\n             211882  page-faults              #      0,003 M/sec\n       177777232502  cycles                   #   2127,119 M/sec\n       200278330301  instructions             #      1,127 IPC\n        21014495344  branches                 #    251,440 M/sec\n         1659583500  branch-misses            #      7,897 %\n         2297603485  cache-references         #     27,491 M/sec\n         1314536406  cache-misses             #     15,729 M/sec\n\n       83,783009768  seconds time elapsed\n\n Performance counter stats for './git fsck --full':\n\n       83288,834113  task-clock-msecs         #      0,998 CPUs\n               8365  context-switches         #      0,000 M/sec\n                  5  CPU-migrations           #      0,000 M/sec\n             174403  page-faults              #      0,002 M/sec\n       177173914267  cycles                   #   2127,223 M/sec\n       200234762879  instructions             #      1,130 IPC\n        21006452953  branches                 #    252,212 M/sec\n         1659600980  branch-misses            #      7,900 %\n         2298086212  cache-references         #     27,592 M/sec\n         1309056989  cache-misses             #     15,717 M/sec\n\n       83,482945132  seconds time elapsed\n\nSigned-off-by: Cesar Eduardo Barros <cesarb@cesarb.net>\n---\n Makefile |   20 ++++++++++++++++++++\n bench.sh |   45 +++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 65 insertions(+), 0 deletions(-)\n create mode 100755 bench.sh\n\ndiff --git a/Makefile b/Makefile\nindex e40ac0c..8eaa8a0 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2486,3 +2486,23 @@ cover_db: coverage-report\n \n cover_db_html: cover_db\n \tcover -report html -outputdir cover_db_html cover_db\n+\n+### Profile feedback based optimization\n+#\n+.PHONY: benchmark profile-generate profile-use profile-optimized-build\n+\n+benchmark:\n+\ttime ./bench.sh\n+\n+profile-generate:\n+\t$(MAKE) clean coverage-clean\n+\t$(MAKE) CFLAGS=\"$(CFLAGS) -fprofile-generate\" LDFLAGS=\"$(LDFLAGS) -fprofile-generate\" all\n+\n+profile-use:\n+\t$(MAKE) clean\n+\t$(MAKE) CFLAGS=\"$(CFLAGS) -fprofile-use\" LDFLAGS=\"$(LDFLAGS) -fprofile-use\" all\n+\n+profile-optimized-build:\n+\t$(MAKE) profile-generate\n+\t$(MAKE) -j1 benchmark\n+\t$(MAKE) profile-use\ndiff --git a/bench.sh b/bench.sh\nnew file mode 100755\nindex 0000000..939f3b3\n--- /dev/null\n+++ b/bench.sh\n@@ -0,0 +1,45 @@\n+#!/bin/bash\n+set -eu\n+\n+BENCHDIR=\"$PWD/bench\"\n+GIT_BUILD_DIR=\"$BENCHDIR/..\"\n+export PATH=\"$GIT_BUILD_DIR/bin-wrappers:$PATH\"\n+\n+mkdir \"$BENCHDIR\"\n+cd \"$BENCHDIR\"\n+\n+git --version\n+exec > bench.log 2>&1\n+\n+for count in `seq 100`; do\n+\n+mkdir \"$BENCHDIR/test\"\n+cd \"$BENCHDIR/test\"\n+git init\n+echo a > a\n+echo b > b\n+git add a b\n+git commit -m 'Commit 1'\n+echo c > c\n+echo d > d\n+git add c d\n+git commit -m 'Commit 2'\n+git checkout -b branch\n+echo e > e\n+echo f > f\n+git add e f\n+git commit -m 'Commit 3'\n+git checkout -\n+echo g > g\n+echo h > h\n+git add g h\n+git commit -m 'Commit 4'\n+git merge branch\n+git fsck --full\n+cd \"$BENCHDIR\"\n+rm -rf test\n+\n+done\n+\n+cd ..\n+rm -rf \"$BENCHDIR\"\n-- \n1.7.4.4\n"}]}