【问题标题】:Multithreaded calculation in excel is slowexcel中的多线程计算很慢
【发布时间】:2023-04-04 14:12:02
【问题描述】:

我想知道是否有任何方法可以控制 excel 计算,以便并行重新计算 WB 中的多个工作表,而其他工作表则没有。我的问题是,在当前设置下,我拥有的顺序计算过程花费了太长时间。该序列由 VBA 驱动,如下所示: 1)vba调用插件(excel-dna vb.net插件,控制数据读取器和附加数据库) 2)插件将数据返回到表1。表2-3按顺序重新计算(表2,然后3) 3) 第 4 到第 10 页按顺序重新计算,但由于每个独立地只链接到第 2 页,理论上它们可以并行重新计算 - 对吧?但是如何做到这一点? 4) 再次开始处理,通过 1) 中描述的 vba 插件调用新数据

在我的笔记本电脑(64 位和 32 位 excel,intel i7)上运行数据子集需要 54.6 秒。有趣的是,如果我关闭多线程,它需要 25.8 秒!更重要的是,如果我在超快机器上运行它(2 x Intel Xeon X5570,四核“Nehalem”架构,64 位和 64 位 excel),它比我的笔记本电脑慢,多线程需要 230 秒或没有多线程需要 26 秒。

我想知道是否有更好的方法可以利用多核和多线程。缓慢的一点似乎是 excel 重新计算而不是插件速度。任何建议表示赞赏。

编辑: 上面的描述有点简化——实际上,我还有一个迭代的“计算/粘贴-vales/重新计算”过程,它在 4-10 的每张纸上运行(迭代继续进行,直到达到一些所需的灵敏度,并且只有然后是计算完整的工作表)。我相信这使得在当前设计下运行 wb 计算不可行。

表 4-10 是相同的(硬编码输入参数除外),并且彼此之间没有计算依赖关系。如果每个计算过程(提到的迭代过程和工作表计算)可以并行而不是顺序完成,我认为整个过程会快得多。

仅供参考,我已经进行了更明显的简化和测试(分解公式、分离 volatile 函数等)。

在整个过程中运行我的整个数据集大约需要 16 个小时,这就是为什么我渴望找到一些方法来改进这一点。

谢谢!

【问题讨论】:

    标签: multithreading performance excel architecture


    【解决方案1】:
    • 这是阅读有关 Excel 计算性能的一个很好的开始:http://www.decisionmodels.com/calcsecretsc.htm

    • 您可以使用 [ExcelFunction(IsThreadSafe=true)] 之类的属性将 Excel-DNA 函数标记为线程安全的,尽管这听起来不像是这里的瓶颈。这将允许同时评估这些函数。

    • 如果您的 i7 处理器具有超线程(因此它向 Windows 报告 4 个内核但实际上只有两个真正的内核),那么将 Excel 线程数设置为内核数会更快(例如2) 而不是处理器可以运行的线程数(这将是 Excel 默认值 - 可能是 4)。

    【讨论】:

    • 嗨,Govert。这方面的 excel-dna 和 dotnet datareader 方面似乎非常有效。无论如何,我根据您的建议对数据子集进行了微定时测试:多线程关闭(28.3);在 + 1 线程 (30.3);在 + 2 线程 (70.8);所有可用的处理器 (65.1)。切换 IsExceptionSafe=True 和 IsThreadSafe=True 没有明显区别(两者都为 false 和 true 都时间为 28.3 秒)。我想知道,如果每张工作表的重新计算命令是从 excel-dna 插件发送的,它是否会以某种方式变得更快?例如,vba 运行 excel-dna 插件,然后发送工作表重新计算命令。
    • 最近有一些与 Excel-DNA 相关的性能讨论和结果:groups.google.com/group/exceldna/browse_frm/thread/…。这似乎表明通过 COM 和 C API 调用工作表计算并没有什么不同。
    • 谢谢。重新讨论之前的讨论。我只是注意到使用 Threadsafe:=True 生成的结果和多线程计算产生了虚假结果。我想我的应用毕竟不是线程安全的......
    【解决方案2】:

    多线程计算比单线程计算慢是很不寻常的。

    大概您已将计算切换为手动。

    您是否在每张工作表上使用 Sheet.Calculate 来“按顺序计算工作表”?如果是这样,只使用 Application.Calculate 并让 Excel 自动找出重新计算所有工作表的最快方法可能会更快。

    【讨论】:

    • 嗨,Charles,我已经阅读了您关于计算速度的博客,并且过去对您的工作有所使用。谢谢你。你是对的 - 我将计算设置为手动并控制 VBA 的计算顺序;调用 excel-dna 插件,将数据加载到第一个工作表中,然后依次计算后续工作表; sheet("Sheet2").calculate、sheet("Sheet3").calculate 等。请参阅我上面的编辑,其中提供了更多详细信息。
    • 为什么不同时迭代所有工作表 4-10?
    • 是的,我非常想同时迭代/计算工作表 4-10(=并行)。但我不知道这怎么可能,除非我运行单独的 excel 实例。如果您知道另一种方式,有兴趣听到另一种方式 - 这真的会触及我问题的本质。
    • 所以 - 使用 Application.Calculate 计算所有工作表(这将是多线程),将值粘贴到第 4-10 个工作表上,然后重复直到所有工作表都收敛。顺便说一句,如果您使用 Range.Calculate 请注意它不是多线程的
    • 我喜欢您的建议,但不幸的是进纸器表 (1-3) 对它们进行了一些繁重的计算,包括易失性公式,因此每个 application.calculate 都会受到该开销的影响。也就是说,你给了我一些值得进一步研究的想法,我可能会看看我是否可以解决开销问题。重新范围。计算;是的,我读到了,谢谢(也许我是在你的网站上读到的)并且在实践中发现它比较慢,所以一直坚持使用 worksheet.calculate。可惜什么都没有;工作表(4-10)。计算!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 2018-05-27
    • 1970-01-01
    相关资源
    最近更新 更多