Skip to content

Instantly share code, notes, and snippets.

@csfrancis
Created July 6, 2014 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csfrancis/9068d7168f6614bbdb41 to your computer and use it in GitHub Desktop.
Save csfrancis/9068d7168f6614bbdb41 to your computer and use it in GitHub Desktop.
Using Luajit's DynAsm to read the timestamp counter using inline assembly in Lua
-- A timer that uses the rdtsc instruction to read the CPU timestamp counter.
--
-- Requires DynAsm with Lua mode: https://github.com/luapower/dynasm
--
-- Use it like this:
--
-- local tsc_timer = require('tsc_timer')
-- local t = tsc_timer.start()
-- ... do some things ...
-- t:stop()
-- print(t:value())
--
-- value() returns the estimated number of milliseconds and the number of ticks elapsed
--
local dynasm = require('dynasm')
local ffi = require('ffi')
local rdtsc = dynasm.loadstring [[
local ffi = require('ffi')
local dasm = require('dasm')
|.arch x64
|.actionlist actions
local Dst = dasm.new(actions)
| rdtsc
| shl rdx, 32
| or rax, rdx
| ret
local code = Dst:build()
return function()
local _ = code
return ffi.cast('uint64_t __cdecl (*)()', code)()
end
]]()
ffi.cdef [[
int usleep(uint32_t usec);
]]
local _M = {}
local mt = { __index = _M }
function _M.initialize()
if _M.ticks_per_sec ~= nil then return end
local start_time = rdtsc()
ffi.C.usleep(200000)
local end_time = rdtsc() - start_time
_M.ticks_per_sec = end_time * 5
end
function _M.start()
if _M.ticks_per_second == nil then _M.initialize() end
return setmetatable({ start_time = rdtsc() }, mt)
end
function _M.stop(self)
local end_time = rdtsc()
if self.start_time == nil then error("timer has not been started") end
if self.stop_time ~= nil then error("timer has already been stopped") end
_M.end_time = end_time
return _M.value(self)
end
function _M.value(self)
return tonumber(self.end_time - self.start_time) / tonumber(self.ticks_per_sec) * 1000, tonumber(self.end_time - self.start_time)
end
return _M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment