Skip to content

Commit

Permalink
Merge #804 (snabbmark mp-ring) into multiproc
Browse files Browse the repository at this point in the history
  • Loading branch information
lukego committed Mar 6, 2016
2 parents ed346d5 + d45f808 commit a5517e0
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
114 changes: 114 additions & 0 deletions src/program/snabbmark/mp.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
-- Multiprocess benchmarks
-- Use of this source code is governed by the Apache 2.0 license; see COPYING.

module(..., package.seeall)

local ffi = require("ffi")
local C = ffi.C
local S = require("syscall")
local pmu = require("lib.pmu")
local lib = require("core.lib")

-- Ring benchmark:
-- See how quickly packets are cycled through a ring of processes.
--
-- Each process copies packets from its input to its output link. Each
-- link is populated with an initial "burst" of packets.
function mp_ring (args)
local function usage ()
print(require("program.snabbmark.README_mp_inc"))
os.exit(1)
end
local long_opts = {
help = "h",
mode = "m",
processes = "n",
packets = "p",
burst = "b",
events = "e",
read = "r",
write = "w"
}
local c = {
mode = "basic",
processes = 2,
packets = 100e6,
burst = 100,
pmuevents = false,
readbytes = 0,
writebytes = 0
}
local opt = {}
function opt.m (arg) c.mode = arg end
function opt.n (arg) c.processes = tonumber(arg) end
function opt.p (arg) c.packets = tonumber(arg) end
function opt.b (arg) c.burst = tonumber(arg) end
function opt.e (arg) c.pmuevents = arg end
function opt.r (arg) c.readbytes = tonumber(arg) end
function opt.w (arg) c.writebytes = tonumber(arg) end
function opt.h (arg) usage() end
local leftover = lib.dogetopt(args, opt, "hn:p:b:e:r:w:", long_opts)
if #leftover > 0 then usage () end
-- Print summary of configuration
print("Benchmark configuration:")
for k, v in pairs(c) do
print(("%12s: %s"):format(k,v))
end
links = {}
-- Create links to connect the processes in a loop
for i = 0, c.processes-1 do
links[i] = link.new(tostring(i))
for j = 1, c.burst do
link.transmit(links[i], packet.allocate())
end
end
-- Create per-process counters
local counters = ffi.cast("uint64_t *",
memory.dma_alloc(c.processes*ffi.sizeof("uint64_t")))
-- Start child processes
if c.pmuevents then error("PMU support NYI") end
local start = C.get_time_ns()
for i = 0, c.processes-1 do
if S.fork() == 0 then
-- Child <i> has affinity to CPU core <i>
S.sched_setaffinity(0, i)
-- terminate when parent does
S.prctl("set_pdeathsig", "hup")
local input = links[i]
local output = links[(i+1) % c.processes]
if c.mode == "basic" then
-- Simple reference implementation in idiomatic Lua.
local acc = ffi.new("uint8_t[1]")
while counters[i] < c.packets do
if not link.empty(input) and not link.full(output) then
local p = link.receive(input)
-- Read some packet data
for j = 0, c.readbytes do
acc[0] = acc[0] + p.data[j]
end
-- Write some packet data
for j = 0, c.writebytes do
p.data[j] = i
end
link.transmit(output, p)
counters[i] = counters[i] + 1
end
-- Sync registers with memory
core.lib.compiler_barrier()
end
else
print("mode not recognized: " .. c.mode)
os.exit(1)
end
os.exit(0)
end
end
-- Spin until enough packets have been processed
while counters[0] < c.packets do
core.lib.compiler_barrier()
end
local finish = C.get_time_ns()
local seconds = tonumber(finish-start)/1e9
local packets = tonumber(counters[0])
print(("%7.2f Mpps ring throughput per process"):format(packets/seconds/1e6))
end
2 changes: 2 additions & 0 deletions src/program/snabbmark/snabbmark.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ function run (args)
solarflare(unpack(args))
elseif command == 'intel1g' and #args >= 2 and #args <= 3 then
intel1g(unpack(args))
elseif command == 'mp-ring' then
require("program.snabbmark.mp").mp_ring(args)
else
print(usage)
main.exit(1)
Expand Down

0 comments on commit a5517e0

Please sign in to comment.