我在这里处理神经网络,但忽略这一点是安全的,因为真正的问题必须处理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)并运行此代码时,对于任何中等大小的网络来说,它都很慢。
现在,我不太明白的是:
答案 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更容易阅读。 (这听起来都像是好博客饲料 - 我应该把它写出来。)