niko skrev:
2. Koden skalar automatiskt till flera processorer. En singeltrådad version med asynkrona anrop kommer att köa alla callbackanrop på samma processor. (Eller är jag ute och cyklar?)
Du cyklar ;). Asynkrona anrop kommer hanteras av trådpoolen, som använder I/O completion ports och optimalt 1 tråd per processor. Windows väljer vilken processor det kommer scheduleras på. I/O completion ports är det överlägset bästa sättet att göra högpreseterande och CPU-skalbara applikationer på.
Skapar du själv flera trådar kommer även dessa iofs scheduleras av Windows till att köras på flera processorer, men det kommer innebära onödiga context-switchar, vilket ger sämre prestanda jämfört med I/O completion ports.
Men visst är det som du säger förmodligen inte kritiskt i det här fallet. Personligen tycker jag det är trevligare att alltid använda asynkron I/O, eftersom det ger en trevlig struktur på koden och samtidigt ger bäst prestanda. Renholms förslag att cacha data är alltid bra.
Om någon vill öka sin förståelse kring prestanda, CPU-skalbarhet eller I/O completion ports kan jag tipsa om ett par artiklar. Se http://msdn.microsoft.com/library/en-us/dndllpro/html/msdn_scalabil.asp från 1995, som faktiskt gäller fortfarande. Lyckligtvis lägger .Net-klasserna ett trevligt abstraktionslager över I/O completion ports, som annars är ganska komplext. Titta även på avsnittet "Thou shalt create lots of threads. The more, the merrier" i artikeln: http://msdn.microsoft.com/workshop/server/iis/tencom.asp. I/O completion ports beskrivs mer detaljerat här: http://www.sysinternals.com/ntw2k/info/comport.shtml
När är det bra att själv skapa trådar? Enligt min uppfattning ska man nästan aldrig göra det om man programmerar .Net. Vill man öka prestanda för I/O-begränsade program är asynkron programmering rätt metod. Har man flera av varandra oberoende CPU-begränsade tunga beräkningar som ska utföras kan man överväga att skapa en tråd per processor för att parallellisera dessa. Enklare är nog ändå att använda ThreadPool.QueueUserWorkItem(), vilket ger samma effekt som att skapa trådar, fast man låter .Net sköta trådhanteringen.