Skip to content

Instantly share code, notes, and snippets.

@pushrax
Created March 5, 2019 04:52
Show Gist options
  • Save pushrax/7a0635168c180b5c74441851084b46fa to your computer and use it in GitHub Desktop.
Save pushrax/7a0635168c180b5c74441851084b46fa to your computer and use it in GitHub Desktop.
// gcc -O2 function_call_overhead.c
#include <stdio.h>
#include <inttypes.h>
#define concat_lower_uint32(high, low) (high = (high << 32) | low);
int __attribute__ ((noinline)) foo() {
return 42;
}
int main() {
uint64_t start0 = 0, start1 = 0, end0 = 0, end1 = 0;
// rdtsc - read time-stamp counter, increases by one every clock cycle
__asm__ __volatile__("rdtsc" : "=a"(start0), "=d"(start1));
foo();
__asm__ __volatile__("rdtsc" : "=a"(end0), "=d"(end1));
concat_lower_uint32(start1, start0);
concat_lower_uint32(end1, end0);
printf("%" PRIu64 " cycles\n", end1 - start1);
return 0;
}
# gem install RubyInline
require "inline"
class Test
def foo
42
end
inline do |builder|
builder.include "<stdint.h>"
builder.prefix <<-C
#define concat_lower_uint32(high, low) (high = (high << 32) | low);
const int iterations = 100;
C
builder.c <<-C
VALUE measure_cycles() {
uint64_t start0 = 0, start1 = 0, end0 = 0, end1 = 0;
ID foo = rb_intern("foo");
VALUE results = rb_ary_new_capa(iterations);
for (int i = 0; i < iterations; i++) {
// rdtsc - read time-stamp counter, increases by one every clock cycle
__asm__ __volatile__("rdtsc" : "=a"(start0), "=d"(start1));
rb_funcall(self, foo, 0);
__asm__ __volatile__("rdtsc" : "=a"(end0), "=d"(end1));
concat_lower_uint32(start1, start0);
concat_lower_uint32(end1, end0);
rb_ary_push(results, LONG2NUM((long)(end1 - start1)));
}
return results;
}
C
end
end
p Test.new.measure_cycles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment