Objective-C:从多个线程调用和复制相同的块

时间:2011-03-28 16:12:43

标签: iphone objective-c neural-network objective-c-blocks objective-c-runtime

我在这里处理神经网络,但忽略这一点是安全的,因为真正的问题必须处理objective-c中的块。这是我的问题。我发现了一种将神经网络转换为可以一次执行的大块的方法。但是,相对于激活网络,它真的非常非常慢。这似乎有点违反直觉。

如果我给你一组嵌套函数,比如

CGFloat answer = sin(cos(gaussian(1.5*x + 2.5*y)) + (.3*d + bias))
//or in block notation
^(CGFloat x, CGFloat y, CGFloat d, CGFloat bias) {
 return sin(cos(gaussian(1.5*x + 2.5*y)) + (.3*d + bias));
};

理论上,多次运行该函数应该比循环通过一堆连接,设置节点活动/非活动等更容易/更快,所有这些基本上都是在最后计算同一个函数。

但是,当我创建一个块(参见线程:how to create function at runtime)并运行此代码时,对于任何中等大小的网络来说,它都很慢。

现在,我不太明白的是:

  1. 复制块时,您究竟要复制什么?
  2. 让我们说,我复制一个块两次,copy1和copy2。如果我在相同的线程上调用copy1和copy2,是否调用了相同的函数?我不完全明白文档对块副本的意义:Apple Block Docs
  3. 现在如果我再次复制copy1和copy2,而是在单独的线程上调用副本,现在这些函数的行为如何?这会导致某种程度的减速,因为每个线程都试图访问同一个块吗?

1 个答案:

答案 0 :(得分:1)

  

复制块时,究竟是什么   你在复制吗?

您正在复制块捕获的任何状态。如果该块没有捕获任何状态 - 该块看起来不是 - 那么副本应该是“空闲的”,因为该块将是一个常量(类似于@“”的工作方式)。

  

让我们说,我复制一个块两次,copy1   和copy2。如果我调用copy1和copy2   在同一个线程上,是一样的   功能叫?我不明白   究竟是什么文件意味着阻止   副本:Apple Block Docs

复制块时,永远不会复制块的代码。只有捕获状态。所以,是的,你将执行完全相同的指令集。

  

现在,如果我再次制作该副本,请复制1   和copy2,但相反,我打电话给   在不同的线程上复制,现在怎么办   功能表现如何?这会导致   某种减速,就像每个线程一样   试图访问同一个块?

块中捕获的数据不受任何方式的多线程访问保护,因此,不会有任何减速(但您可能会想到所有并发同步的乐趣)。

您是否尝试过对应用程序进行采样以查看消耗CPU周期的内容?另外,考虑到你的目的,你可能想要熟悉友好的本地反汇编程序(otool -TtVv binary/or/.o/file),因为它可以非常有助于确定块副本的实际成本。


如果您正在采样并在块本身中看到大量时间,那么这只是您的计算消耗大量的CPU时间。如果块在复制期间消耗CPU,您将在复制助手中看到消耗。

尝试创建包含许多不同类型块的源文件;带参数,没有,带有捕获状态,没有捕获的带有/不带捕获状态的块等等。还有一个在每个上调用Block_copy()的函数。

反汇编,您将深入了解复制块时会发生什么。就个人而言,我发现x86_64程序集比ARM更容易阅读。 (这听起来都像是好博客饲料 - 我应该把它写出来。)