aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--src/keeper.c14
-rw-r--r--tests/linda_perf.lua130
3 files changed, 66 insertions, 81 deletions
diff --git a/CHANGES b/CHANGES
index d1c4913..c2b14ed 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 93: BGe 20-Jan-14
4 * slightly improve linda performance when the producer/consumer scenario leaves leave the key empty
5
3CHANGE 92: BGe 20-Jan-14 6CHANGE 92: BGe 20-Jan-14
4 * version 3.8.1 7 * version 3.8.1
5 * new function lane:get_debug_threadname() 8 * new function lane:get_debug_threadname()
diff --git a/src/keeper.c b/src/keeper.c
index b0db8b4..1a696aa 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -127,14 +127,14 @@ static void fifo_peek( lua_State* L, keeper_fifo* fifo, int count_)
127 127
128// in: fifo 128// in: fifo
129// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number) 129// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number)
130static void fifo_pop( lua_State* L, keeper_fifo* fifo, int _count) 130static void fifo_pop( lua_State* L, keeper_fifo* fifo, int count_)
131{ 131{
132 int fifo_idx = lua_gettop( L); // ... fifo 132 int fifo_idx = lua_gettop( L); // ... fifo
133 int i; 133 int i;
134 // each iteration pushes a value on the stack! 134 // each iteration pushes a value on the stack!
135 STACK_GROW( L, _count + 2); 135 STACK_GROW( L, count_ + 2);
136 // skip first item, we will push it last 136 // skip first item, we will push it last
137 for( i = 1; i < _count; ++ i) 137 for( i = 1; i < count_; ++ i)
138 { 138 {
139 int const at = fifo->first + i; 139 int const at = fifo->first + i;
140 // push item on the stack 140 // push item on the stack
@@ -151,8 +151,12 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo, int _count)
151 lua_rawseti( L, fifo_idx, at); // ... fifo vals val 151 lua_rawseti( L, fifo_idx, at); // ... fifo vals val
152 lua_replace( L, fifo_idx); // ... vals 152 lua_replace( L, fifo_idx); // ... vals
153 } 153 }
154 fifo->first += _count; 154 {
155 fifo->count -= _count; 155 // avoid ever-growing indexes by resetting each time we detect the fifo is empty
156 int const new_count = fifo->count - count_;
157 fifo->first = (new_count == 0) ? 1 : (fifo->first + count_);
158 fifo->count = new_count;
159 }
156} 160}
157 161
158// in: linda_ud expected at *absolute* stack slot idx 162// in: linda_ud expected at *absolute* stack slot idx
diff --git a/tests/linda_perf.lua b/tests/linda_perf.lua
index 9348f71..1d92c8e 100644
--- a/tests/linda_perf.lua
+++ b/tests/linda_perf.lua
@@ -6,7 +6,9 @@ local table_unpack = unpack or table.unpack
6 6
7-- this lane eats items in the linda one by one 7-- this lane eats items in the linda one by one
8local eater = function( l, loop) 8local eater = function( l, loop)
9 local key, val = l:receive( "go") 9 -- wait for start signal
10 l:receive( "go")
11 -- eat data one by one
10 for i = 1, loop do 12 for i = 1, loop do
11 local val, key = l:receive( "key") 13 local val, key = l:receive( "key")
12 --print( val) 14 --print( val)
@@ -18,7 +20,9 @@ end
18 20
19-- this lane eats items in the linda in batches 21-- this lane eats items in the linda in batches
20local batched = function( l, loop, batch) 22local batched = function( l, loop, batch)
21 local key, val = l:receive( "go") 23 -- wait for start signal
24 l:receive( "go")
25 -- eat data in batches
22 for i = 1, loop/batch do 26 for i = 1, loop/batch do
23 l:receive( l.batched, "key", batch) 27 l:receive( l.batched, "key", batch)
24 end 28 end
@@ -30,6 +34,7 @@ end
30local lane_eater_gen = lanes.gen( "*", eater) 34local lane_eater_gen = lanes.gen( "*", eater)
31local lane_batched_gen = lanes.gen( "*", batched) 35local lane_batched_gen = lanes.gen( "*", batched)
32 36
37-- main thread writes data while a lane reads it
33local function ziva( preloop, loop, batch) 38local function ziva( preloop, loop, batch)
34 -- prefill the linda a bit to increase fifo stress 39 -- prefill the linda a bit to increase fifo stress
35 local top = math.max( preloop, loop) 40 local top = math.max( preloop, loop)
@@ -38,8 +43,8 @@ local function ziva( preloop, loop, batch)
38 for i = 1, preloop do 43 for i = 1, preloop do
39 l:send( "key", i) 44 l:send( "key", i)
40 end 45 end
41 print( l:count( "key")) 46 print( "stored " .. l:count( "key") .. " items in the linda before starting consumer lane")
42 if batch then 47 if batch > 0 then
43 if l.batched then 48 if l.batched then
44 lane = lane_batched_gen( l, top, batch) 49 lane = lane_batched_gen( l, top, batch)
45 else 50 else
@@ -49,12 +54,21 @@ local function ziva( preloop, loop, batch)
49 else 54 else
50 lane = lane_eater_gen( l, top) 55 lane = lane_eater_gen( l, top)
51 end 56 end
52 -- tell the lanes they can start eating data 57 -- tell the consumer lane it can start eating data
53 l:send("go", "go") 58 l:send( "go", true)
54 -- send the remainder of the elements while they are consumed 59 -- send the remainder of the elements while they are consumed
60 -- create a function that can send several values in one shot
61 batch = math.max( batch, 1)
62 local batch_values = {}
63 for i = 1, batch do
64 table.insert( batch_values, i)
65 end
66 local batch_send = function()
67 l:send( "key", table_unpack( batch_values))
68 end
55 if loop > preloop then 69 if loop > preloop then
56 for i = preloop + 1, loop do 70 for i = preloop + 1, loop, batch do
57 l:send( "key", i) 71 batch_send()
58 end 72 end
59 end 73 end
60 l:send( "done" ,"are you happy?") 74 l:send( "done" ,"are you happy?")
@@ -62,33 +76,25 @@ local function ziva( preloop, loop, batch)
62 return lanes.now_secs() - t1 76 return lanes.now_secs() - t1
63end 77end
64 78
65local tests = 79local tests1 =
66{ 80{
67 --[[{ 2000000, 0}, 81 --[[
68 { 3000000, 0}, 82 { 10000, 2000000, 0},
69 { 4000000, 0}, 83 { 10000, 2000000, 1},
70 { 5000000, 0}, 84 { 10000, 2000000, 2},
71 { 6000000, 0},]] 85 { 10000, 2000000, 3},
72 --[[{ 1000000, 2000000}, 86 { 10000, 2000000, 5},
73 { 2000000, 3000000}, 87 { 10000, 2000000, 8},
74 { 3000000, 4000000}, 88 { 10000, 2000000, 13},
75 { 4000000, 5000000}, 89 { 10000, 2000000, 21},
76 { 5000000, 6000000},]] 90 { 10000, 2000000, 44},
77 --[[{ 4000000, 0}, 91 --]]
78 { 4000000, 0, 1},
79 { 4000000, 0, 2},
80 { 4000000, 0, 3},
81 { 4000000, 0, 5},
82 { 4000000, 0, 8},
83 { 4000000, 0, 13},
84 { 4000000, 0, 21},
85 { 4000000, 0, 44},]]
86} 92}
87print "tests #1" 93print "############################################\ntests #1"
88for k, v in pairs( tests) do 94for k, v in pairs( tests1) do
89 local pre, loop, batch = v[1], v[2], v[3] 95 local pre, loop, batch = v[1], v[2], v[3]
90 print( "testing", pre, loop, batch) 96 print( "testing", pre, loop, batch)
91 print( pre, loop, batch, "duration = " .. ziva( pre, loop, batch)) 97 print( pre, loop, batch, "duration = " .. ziva( pre, loop, batch) .. "\n")
92end 98end
93 99
94--[[ 100--[[
@@ -124,6 +130,7 @@ end
124 ziva( 4000000, 0, 44) -> 2s 130 ziva( 4000000, 0, 44) -> 2s
125]] 131]]
126 132
133-- sequential write/read (no parallelization involved)
127local function ziva2( preloop, loop, batch) 134local function ziva2( preloop, loop, batch)
128 local l = lanes.linda() 135 local l = lanes.linda()
129 -- prefill the linda a bit to increase fifo stress 136 -- prefill the linda a bit to increase fifo stress
@@ -154,6 +161,7 @@ local function ziva2( preloop, loop, batch)
154 for i = 1, preloop, step do 161 for i = 1, preloop, step do
155 batch_send() 162 batch_send()
156 end 163 end
164 print( "stored " .. (l:count( "key") or 0) .. " items in the linda before starting consumer lane")
157 -- loop that alternatively sends and reads data off the linda 165 -- loop that alternatively sends and reads data off the linda
158 if loop > preloop then 166 if loop > preloop then
159 for i = preloop + 1, loop, step do 167 for i = preloop + 1, loop, step do
@@ -170,16 +178,8 @@ end
170 178
171local tests2 = 179local tests2 =
172{ 180{
173 --[[{ 2000000, 0}, 181 -- prefill, then consume everything
174 { 3000000, 0}, 182 --[[
175 { 4000000, 0},
176 { 5000000, 0},
177 { 6000000, 0},
178 { 1000000, 2000000},
179 { 2000000, 3000000},
180 { 3000000, 4000000},
181 { 4000000, 5000000},
182 { 5000000, 6000000},]]
183 { 4000000, 0}, 183 { 4000000, 0},
184 { 4000000, 0, 1}, 184 { 4000000, 0, 1},
185 { 4000000, 0, 2}, 185 { 4000000, 0, 2},
@@ -189,44 +189,22 @@ local tests2 =
189 { 4000000, 0, 13}, 189 { 4000000, 0, 13},
190 { 4000000, 0, 21}, 190 { 4000000, 0, 21},
191 { 4000000, 0, 44}, 191 { 4000000, 0, 44},
192 --]]
193 -- alternatively fill and consume
194 { 0, 4000000},
195 { 0, 4000000, 1},
196 { 0, 4000000, 2},
197 { 0, 4000000, 3},
198 { 0, 4000000, 5},
199 { 0, 4000000, 8},
200 { 0, 4000000, 13},
201 { 0, 4000000, 21},
202 { 0, 4000000, 44},
192} 203}
193 204
194print "tests #2" 205print "\n############################################\ntests #2"
195for k, v in pairs( tests2) do 206for k, v in pairs( tests2) do
196 local pre, loop, batch = v[1], v[2], v[3] 207 local pre, loop, batch = v[1], v[2], v[3]
197 print( "testing", pre, loop, batch) 208 print( "testing", pre, loop, batch)
198 print( pre, loop, batch, "duration = " .. ziva2( pre, loop, batch)) 209 print( pre, loop, batch, "duration = " .. ziva2( pre, loop, batch) .. "\n")
199end 210end
200
201--[[
202 V 2.1.0:
203 ziva( 20000, 0) -> 3s ziva( 10000, 20000) -> 3s
204 ziva( 30000, 0) -> 8s ziva( 20000, 30000) -> 7s
205 ziva( 40000, 0) -> 15s ziva( 30000, 40000) -> 14s
206 ziva( 50000, 0) -> 24s ziva( 40000, 50000) -> 22s
207 ziva( 60000, 0) -> 34s ziva( 50000, 60000) -> 33s
208
209 SIMPLIFIED:
210 ziva( 20000, 0) -> 4s ziva( 10000, 20000) -> 3s
211 ziva( 30000, 0) -> 8s ziva( 20000, 30000) -> 7s
212 ziva( 40000, 0) -> 14s ziva( 30000, 40000) -> 14s
213 ziva( 50000, 0) -> 23s ziva( 40000, 50000) -> 22s
214 ziva( 60000, 0) -> 33s ziva( 50000, 60000) -> 32s
215
216 FIFO:
217 ziva( 2000000, 0) -> 9s ziva( 1000000, 2000000) -> 14s
218 ziva( 3000000, 0) -> 14s ziva( 2000000, 3000000) -> 23s
219 ziva( 4000000, 0) -> 19s ziva( 3000000, 4000000) -> 23s
220 ziva( 5000000, 0) -> 24s ziva( 4000000, 5000000) -> 32s
221 ziva( 6000000, 0) -> 29s ziva( 5000000, 6000000) -> 33s
222
223 FIFO BATCHED:
224 ziva( 4000000, 0, 1) -> 19s
225 ziva( 4000000, 0, 2) -> 11s
226 ziva( 4000000, 0, 3) -> s
227 ziva( 4000000, 0, 5) -> s
228 ziva( 4000000, 0, 8) -> s
229 ziva( 4000000, 0, 13) -> s
230 ziva( 4000000, 0, 21) -> s
231 ziva( 4000000, 0, 44) -> s
232]]