簡體   English   中英

異步等待增加上下文切換

[英]Does async await increases Context switching

我知道異步等待是如何工作的。 我知道當執行到達等待時,它釋放線程並在IO完成后,它從線程池中獲取線程並運行剩余的代碼。 這樣就可以有效地利用線程。 但我在一些用例中感到困惑:

  1. 我們是否應該使用異步方法來實現非常快速的IO方法,比如緩存讀/寫方法? 它們不會導致不必要的上下文切換。 如果我們使用sync方法,則執行將在同一線程上完成,並且上下文切換可能不會發生。
  2. Async-await是否僅保存內存消耗(通過創建較少的線程)。 或者它也節省了CPU? 據我所知,在同步IO的情況下,當IO發生時,線程進入睡眠模式。 這意味着它不消耗CPU。 這種理解是否正確?

我知道異步等待是如何工作的。

你不是。

我知道當執行到達等待時,它會釋放線程

它不是。 當執行到達等待時,將評估等待的操作數,然后檢查操作是否完成。 如果不是,那么該方法的其余部分被注冊為等待的繼續,並且表示當前方法的工作的任務被返回給調用者。

這些都不是“釋放線程”。 相反, 控制返回給調用者 ,調用者繼續在當前線程上執行。 當然,如果當前調用者是這個線程上的唯一東西,那么線程就完成了。 但是並不要求異步方法是線程上的唯一調用!

IO完成后

等待的不一定是IO操作,但我們假設它是。

它從線程池中獲取線程並運行剩余的代碼。

不會 。它會安排剩余的代碼在正確的上下文中運行 該上下文可能是一個線程池線程。 它可能是UI線程。 它可能是當前的線程。 它可能是任何數量的東西。

我們是否應該使用異步方法來實現非常快速的IO方法,比如緩存讀/寫方法?

等待評估。 如果等待者知道它可以在合理的時間內完成操作,則完全有權進行操作並返回完成的任務。 在這種情況下,沒有罰款; 你只是檢查一個布爾值來查看任務是否完成。

它們不會導致不必要的上下文切換。

不必要。

如果我們使用sync方法,則執行將在同一線程上完成,並且上下文切換可能不會發生。

我很困惑為什么你認為在IO操作上發生了上下文切換。 IO操作在硬件上運行,低於OS線程級別。 沒有任何線程可以為IO任務提供服務。

Async-await是否僅保存內存消耗(通過創建較少的線程)

等待的目的是(1)通過允許工作流變得更加異步,從而在等待高延遲結果的同時釋放線程來工作,以及(2)制作源代碼,從而更有效地使用昂貴的工作線程異步工作流程類似於同步工作流程的源代碼。

據我所知,在同步IO的情況下,當IO發生時,線程進入睡眠模式。 這意味着它不消耗CPU。 這種理解是否正確?

當然,你完全倒退了。 你想要消耗CPU 你想要一直消耗盡可能多的CPU! 該CPU是做代表用戶工作 ,如果是閑置那么它沒有得到它的工作速度,因為它可以完成。 不要雇佣工人,然后付錢讓他們入睡! 雇用一名工人,一旦他們被阻塞在高延遲任務上,就讓他們去做其他工作,這樣 CPU就會一直保持熱度。 該機器的所有者為該CPU支付了很多錢; 它應該始終以100%運行才能完成工作!

那么讓我們回到你的基本問題:

異步等待增加上下文切換

我知道一個很好的方法可以找到答案。 使用await編寫程序,不用編寫另一個程序,同時運行它們 ,並測量每秒的上下文切換次數。 然后你就會知道。

但我不明白為什么每秒上下文切換是一個相關的指標。 讓我們考慮兩家擁有大量客戶和大量員工的銀行。 在銀行#1,員工完成一項任務直至完成; 他們從不改變背景。 如果員工在等待另一個員工的結果時被阻止,他們會進入睡眠狀態。 在銀行#2,員工在被阻止時從一個任務切換到另一個任務,並且不斷地為客戶請求提供服務。 您認為哪家銀行有更快的客戶服務?

我們是否應該使用異步方法來實現非常快速的IO方法,比如緩存讀/寫方法?

這樣的IO不會在經典意義上阻止。 “阻止”是一個松散定義的術語。 通常,這意味着CPU必須等待硬件。

這種類型的IO純粹是CPU工作,沒有上下文切換。 如果應用程序讀取文件或套接字的速度慢於可以提供的數據,則通常會發生這種情況。 在這里,異步IO根本無助於性能。 我甚至不確定是否適合解除UI線程的阻塞,因為所有任務可能同步完成。

或者它也節省了CPU?

它通常會增加實際負載中的CPU使用率。 這是因為異步機器增加了處理,分配和同步。 此外,我們需要轉換到內核模式兩次而不是一次(首先啟動IO,然后將IO完成通知出列)。

典型工作負載使用<< 100%CPU運行。 具有> 60%CPU的生產服務器會擔心我,因為沒有錯誤余量。 在這種情況下,線程池工作隊列幾乎總是空的。 因此,在一個上下文切換上處理多個IO完成不會導致上下文切換節省。

這就是為什么CPU使用率通常會增加(略微),除非機器的CPU負載非常高並且工作隊列通常能夠立即提供新項目。

在服務器上,異步IO主要用於保存線程。 如果您有足夠的線程可用,您將實現零或負增益。 特別是任何單個IO都不會快一點。

這意味着它不消耗CPU。

在IO正在進行時,讓CPU不可用將是一種浪費。 對內核而言,IO只是一種數據結構。 在它正在進行的過程中,沒有CPU工作要做。

一位匿名人士說:

對於IO綁定任務,使用單獨的線程來等待結果可能沒有主要的性能優勢。

將相同的工作推送到不同的線程肯定無助於吞吐量。 這是增加的工作,而不是減少工作。 這是一個貝殼游戲。 (並且async IO在運行時不使用線程,因此所有這些都基於錯誤的假設。)

一個簡單的方法來說服自己異步IO通常比同步IO花費更多的CPU是運行簡單的TCP ping / pong基准同步和異步。 同步更快。 這是一種人為的負載,所以它只是暗示正在發生的事情,而不是一個全面的測量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM