rust 在同步代码中使用async/await有什么性能优势吗?

f1tvaqid  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(174)

我试图了解何时使用异步,何时它可以提高性能。
我知道它在替换其他阻塞IO操作(如文件IO、http调用、数据库操作等)方面最强大,但我想知道是否还有其他意义(至少就性能而言)。
一个具体的例子可能是大的内存副本(移动一个大的向量或以其他方式复制大量数据)。这是一个同步操作,就程序的其余部分而言,可能需要一段时间。这个例子可以利用async/await来做其他事情,而我们等待副本,或者线程必须等待内存副本才能继续执行?
如果不是这个直接的例子,也许是另一个可以通过async/await改进的同步操作?

zqdjd7g9

zqdjd7g91#

Async/await不会给予任何parallelism, only concurrency。这意味着任何使用async/await来划分工作的同步操作都将一部分接一部分地运行,并不比没有async/await更快,实际上更慢,因为它增加了开销。
您只能通过线程获得并行性,并且系统中的内核数量有限。
一些异步运行时使用多个线程并行运行代码,因此如果正确使用它们,您将获得一些并行性(因此速度);但是这只会增加直接使用线程的开销,或者使用像rayon这样的库来避免async/await,并且只使用线程来并行化代码。
如果你没有I/O绑定,不要使用async/await。你什么也得不到。

yhived7q

yhived7q2#

理论上是的
在CppCon 2015上,Gor Nishanov展示了他在C的实验性协同程序实现方面的工作:C++ coroutines - a negative overhead abstraction. C协同程序与Rust async/await有些不同(甚至在实现方面),但区别在这里并不重要。
演讲的关键亮点是某些算法可以通过利用内存预取来使用协程来提高速度。虽然从代码的Angular 来看,内存访问通常是同步的,但实际上在CPU级别上是异步的。那么,诀窍在于:

  • 触发预取。
  • 暂停执行--做点别的。
  • 恢复执行,此时预取的存储器应在L1中,立即可用。

现在,值得注意的是,协同程序(或async/await)并不是特别 * 需要 * 来实现这种效果。它们毕竟只是一个抽象概念。尽管如此,抽象允许以更简洁/更有表现力的方式表达。
因此,在实践中,许多所谓的“同步”算法可以通过async/await进行优化,利用CPU异步操作。

相关问题