0

我在这里处理神经网络,但忽略它是安全的,因为真正的问题必须处理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));
};

从理论上讲,多次运行该函数应该比遍历一堆连接以及设置节点活动/非活动等更容易/更快,所有这些最终都会计算出相同的函数。

但是,当我创建一个块(请参阅线程:如何在运行时创建函数)并运行此代码时,对于任何中等规模的网络来说,它都非常慢。

现在,我不太明白的是:

  1. 当你复制一个块时,你到底在复制什么?
  2. 比方说,我复制一个块两次,copy1 和 copy2。如果我在同一个线程上调用 copy1 和 copy2 ,是否调用了同一个函数?我不明白文档对块副本的确切含义:Apple Block Docs
  3. 现在,如果我再次制作该副本,copy1 和 copy2,但相反,我在单独的线程上调用副本,那么这些函数的行为如何?当每个线程都试图访问同一个块时,这是否会导致某种减速?
4

1 回答 1

1

当你复制一个块时,你到底在复制什么?

您正在复制块捕获的任何状态。如果该块没有捕获任何状态——该块似乎没有——那么副本应该是“自由的”,因为该块将是一个常量(类似于 @"" 的工作方式)。

比方说,我复制一个块两次,copy1 和 copy2。如果我在同一个线程上调用 copy1 和 copy2,是否调用了同一个函数?我不明白文档对块副本的确切含义:Apple Block Docs

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

现在,如果我再次制作该副本,copy1 和 copy2,但相反,我在单独的线程上调用副本,那么这些函数的行为如何?当每个线程都试图访问同一个块时,这是否会导致某种减速?

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

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


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

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

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

于 2011-03-28T16:49:48.293 回答