#!/usr/bin/env python
# coding: utf-8

# # Pipeline Performance Mysteries

# Consider setting power profiles, see `cpupower-gui`.

# In[11]:


get_ipython().system('LANG= cpupower frequency-info')


# In[12]:


get_ipython().system('rm -Rf tmp')
get_ipython().system('mkdir -p tmp')


# In[13]:


get_ipython().run_cell_magic('writefile', 'tmp/pipeline-perf.c', '\n#include <stdio.h>\n#include "timing.h"\n\n\nint main()\n{\n  int result = 0;\n\n  {\n    int a = 0, b = 0;\n\n    timestamp_type t1;\n    get_timestamp(&t1);\n\n    for (int ntrips = 0; ntrips < 1000; ++ntrips)\n      for (int i = 0; i< 400*1000; ++i)\n      {\n        a += i;\n        a += i;\n      }\n\n    timestamp_type t2;\n    get_timestamp(&t2);\n\n    printf("a, a: elapsed time %g s\\n",\n        timestamp_diff_in_seconds(t1, t2));\n    result += a+b;\n  }\n\n  return result;\n}\n')


# In[14]:


get_ipython().system('cd tmp; gcc -std=gnu99 -lrt -I.. -opipeline-perf pipeline-perf.c')
get_ipython().system('tmp/pipeline-perf')


# Check that the compiler didn't do anything unexpected:

# In[15]:


# !objdump --disassemble tmp/pipeline-perf


# Come up with variants of this that exhibit various behaviors of the execution pipeline:

# In[ ]:





# In[16]:


get_ipython().system('cd tmp; gcc -std=gnu99 -lrt -I.. -opipeline-perf pipeline-perf.c')
get_ipython().system('tmp/pipeline-perf')


# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# * Scroll down for solution
# 

# In[17]:


get_ipython().run_cell_magic('writefile', 'tmp/pipeline-perf.c', '\n#include <stdio.h>\n#include "timing.h"\n\n\nint main()\n{\n  int result = 0;\n\n  {\n    int a = 0, b = 0;\n\n    timestamp_type t1;\n    get_timestamp(&t1);\n\n    for (int ntrips = 0; ntrips < 1000; ++ntrips)\n      for (int i = 0; i< 1000*1000; ++i)\n      {\n        a += i;\n        a += i;\n      }\n\n    timestamp_type t2;\n    get_timestamp(&t2);\n\n    printf("a, a: elapsed time %g s\\n",\n        timestamp_diff_in_seconds(t1, t2));\n    result += a+b;\n  }\n\n  {\n    int a = 0, b = 0;\n\n    timestamp_type t1;\n    get_timestamp(&t1);\n\n    for (int ntrips = 0; ntrips < 1000; ++ntrips)\n      for (int i = 0; i< 1000*1000; ++i)\n      {\n        a += i;\n        b += i;\n      }\n\n    timestamp_type t2;\n    get_timestamp(&t2);\n\n    printf("a, b: elapsed time %g s\\n",\n        timestamp_diff_in_seconds(t1, t2));\n    result += a+b;\n  }\n\n  {\n    int a = 0, b = 0;\n\n    timestamp_type t1;\n    get_timestamp(&t1);\n\n    for (int ntrips = 0; ntrips < 1000; ++ntrips)\n      for (int i = 0; i< 250*1000; ++i)\n      {\n        a += i;\n        a += i;\n \n        a += i;\n        a += i;\n \n        a += i;\n        a += i;\n \n        a += i;\n        a += i;\n \n      }\n\n    timestamp_type t2;\n    get_timestamp(&t2);\n\n    printf("a, a unrolled: elapsed time %g s\\n",\n        timestamp_diff_in_seconds(t1, t2));\n    result += a+b;\n  }\n  {\n    int a = 0, b = 0;\n\n    timestamp_type t1;\n    get_timestamp(&t1);\n\n    for (int ntrips = 0; ntrips < 1000; ++ntrips)\n      for (int i = 0; i< 250*1000; ++i)\n      {\n        a += i;\n        a += i;\n        a += i;\n        a += i;\n          \n        b += i;\n        b += i;\n        b += i;\n        b += i;\n      }\n\n    timestamp_type t2;\n    get_timestamp(&t2);\n\n    printf("aa, bb unrolled: elapsed time %g s\\n",\n        timestamp_diff_in_seconds(t1, t2));\n    result += a+b;\n  }\n\n  {\n    int a = 0, b = 0;\n\n    timestamp_type t1;\n    get_timestamp(&t1);\n\n    for (int ntrips = 0; ntrips < 1000; ++ntrips)\n      for (int i = 0; i< 250*1000; ++i)\n      {\n        a += i;\n        b += i;\n\n        a += i;\n        b += i;\n\n        a += i;\n        b += i;\n\n        a += i;\n        b += i;\n      }\n\n    timestamp_type t2;\n    get_timestamp(&t2);\n\n    printf("a, b unrolled: elapsed time %g s\\n",\n        timestamp_diff_in_seconds(t1, t2));\n    result += a+b;\n  }\n\n  return result;\n}\n')


# In[18]:


get_ipython().system('cd tmp; gcc -std=gnu99 -lrt -I.. -opipeline-perf pipeline-perf.c')
get_ipython().system('tmp/pipeline-perf')


# In[ ]:




