模拟Lua中的并行性

时间:2016-11-14 16:50:58

标签: lua parallel-processing prototype

我正在尝试使用lua来构建一些并行算法。有了这个,我的意思是用纯Lua编写代码,对它执行测试,调试它等等。然后,当我确信它有效时,我可以将它转换为真正的多线程库,甚至是另一种语言(例如OpenCL kenel) )。显然,我并不关心原型代码的性能。

我想在每一行都使用一个协同程序,用一些样板随机选择下一个“Thread”来运行。例如:

local function parallel_simulation(...)

  local function_list = {...}
  local coroutine_list = {}
  local thread_number = #function_list
  for i = 1, thread_number do
    coroutine_list[i] = coroutine.create(function_list[i])
  end

  while 0 < thread_number do

    local current = math.random(1, thread_number)
    local worker = coroutine_list[current]

    coroutine.resume(worker)

    if 'dead' == coroutine.status(worker) then
      thread_number = thread_number - 1
      table.remove(coroutine_list, current)
    end
  end
end

----------------------------------------------------------
-- Usage example

local Y = coroutine.yield
local max = 3
local counter = 0
local retry = 99

local function increment()
  Y() local c = counter
  Y() while max > c do
  Y()   c = counter
  Y()   c = c + 1
  Y()   counter = c
  Y() end
end

for i=1,retry do
  counter = 0
  parallel_simulation(increment, increment)
  if max ~= counter then
    print('Test SUCCESS ! A non-thread-safe algorithm was identified .', i, counter)
    return
  end
end

error('Test FAIL ! The non-thread-safe algorithm was not identified .')

这只是一个想法,任何涉及纯Lua的解决方案都是受欢迎的!让我对这个解决方案感到非常不舒服的是Y()。有什么方法可以避免它们吗? (debug.sethook不允许产生...)

编辑1 - 提供了更有意义的例子

编辑2 - 希望,我澄清了我想要完成的事情

1 个答案:

答案 0 :(得分:0)

Y()放在每行前面的简单替代方法是使用gsubload

Y = coroutine.yield
max = 3
counter = 0

code = [[
function increment()
  local c = counter
  while max > c do
    c = counter
    c = c + 1
    counter = c
  end
end]]
code = code:gsub("\n  ", "\n  Y() ") -- replace two spaces in find/replace with whatever tab character(s) you use
assert(load(code))()

local retry = 99
-- rest of code here

(根据您的Lua版本,使用loadloadstring) 请注意,变量声明Y / max / counter必须是全局的,否则加载的函数将无法访问它们。同样,code中的函数必须是全局的,否则increment将不会存在于加载的代码之外。

这样的解决方案假定每行上的所有指令都是原子/线程安全的。

我建议对parallel_simulation进行的改进是添加一些改变下一个线程选择方式的方法。例如,如果其中一个线程处于执行的早期阶段,而另一个线程几乎完成,则可能只会显示错误 - 虽然理论上可以通过足够的随机试验达到这个状态,但是有一个参数允许您调整哪些线程更多可能会被选择(使用权重)应该更有可能。