Windows 7

ClearType in Windows 7

One of my big pet peeves with ClearType prior to Win­dows 7 was that it only anti-aliased hor­i­zon­tally with sub-pix­els. This is great for small fonts, be­cause at such a small scale tra­di­tional anti-alias­ing has a smudg­ing ef­fect, re­duc­ing clar­ity and in­creas­ing the font’s weight. For large fonts how­ever, it in­tro­duces some very no­tice­able alias­ing on curves, as best seen in the ‘6′ and ‘g’ here:

"Int64.org" rendered with GDI

You’ve prob­a­bly no­ticed this on web­sites every­where, but have come to ac­cept it. De­pend­ing on your browser and op­er­at­ing sys­tem, you can prob­a­bly see it in the title here. This prob­lem is solved in Win­dows 7 with the in­tro­duc­tion of Di­rectWrite, which com­bines ClearType’s hor­i­zon­tal anti-alias­ing with reg­u­lar ver­ti­cal anti-alias­ing when using large font sizes:

"Int64.org" rendered with DirectWrite

Of course, Di­rectWrite af­fects more than just Latin char­ac­ters. Any glyphs with very slight an­gles will see a huge ben­e­fit, such as hi­ra­gana:

"まこと" rendered with GDI and DirectWrite

Un­for­tu­nately, this isn’t a free up­grade. For what­ever rea­son, Mi­crosoft didn’t make all the old GDI func­tions use Di­rectWrite’s im­prove­ments so to make use of this, all your old GDI and Draw­Text code will need to be up­graded to use Di­rec­t2D and Di­rectWrite di­rectly, so an old WM_PAINT pro­ce­dure like this:

PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);

HFONT font = CreateFont(-96, 0, 0, 0, FW_NORMAL,
                        0, 0, 0, 0, 0, 0, 0, 0, L"Calibri");

SelectObject(hdc, (HGDIOBJ)font);

RECT rc;
GetClientRect(hwnd, &rc);

DrawText(hdc, L"Int64.org", 9, &rc,
         DT_SINGLELINE | DT_CENTER | DT_VCENTER);

EndPaint(hwnd, &ps);

Will turn into this:

ID2D1Factory *d2df;

D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
   __uuidof(ID2D1Factory), 0, (void**)&d2df);

IDWriteFactory *dwf;

DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
   __uuidof(IDWriteFactory), (IUnknown**)&dwf);

IDWriteTextFormat *dwfmt;

dwf->CreateTextFormat(L"Calibri", 0, DWRITE_FONT_WEIGHT_REGULAR,
   DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL,
   96.0f, L"en-us", &dwfmt);

dwfmt->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
dwfmt->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

RECT rc;
GetClientRect(hwnd, &rc);

D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left,
                               rc.bottom - rc.top);

ID2D1HwndRenderTarget *d2drt;

d2df->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
   D2D1::HwndRenderTargetProperties(hwnd, size), &d2drt);

ID2D1SolidColorBrush *d2db;

d2drt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black),
   &d2db);

D2D1_SIZE_F layoutSize = d2drt->GetSize();
D2D1_RECT_F layoutRect = D2D1::RectF(0.0, 0.0,
   layoutSize.width, layoutSize.height);

d2drt->BeginDraw();
d2drt->DrawText(L"Int64.org", 9, dwfmt, layoutRect, d2db);
d2drt->EndDraw();

This is no small change, and con­sid­er­ing this API won’t work on any­thing but Vista and Win­dows 7, you’ll be cut­ting out a lot of users if you spe­cial­ize for it. While you could prob­a­bly make a clever Draw­Text wrap­per, Di­rec­t2D and Di­rectWrite are re­ally set up to get you the most ben­e­fit if you’re all in. Hope­fully gen­eral li­braries like Pango and Cairo will get up­dated back­ends for it.

Di­rectWrite has other ben­e­fits too, like sub-pixel ren­der­ing. When you ren­der text in GDI, glyphs will al­ways get snapped to pix­els. If you have two let­ters side by side, it will choose to al­ways start the next let­ter 1 or 2 pix­els away from the last—but what if the cur­rent font size says it should ac­tu­ally be a 1.5 pixel dis­tance? In GDI, this will be rounded to 1 or 2. This is also no­tice­able with kern­ing, which tries to re­move ex­ces­sive space be­tween spe­cific glyphs such as “Vo”. Be­cause of this, most of the text you see in GDI is very slightly warped. It’s much more ap­par­ent when an­i­mat­ing, where it causes the text to have a wob­bling ef­fect as it con­stantly snaps from one pixel to the next in­stead of smoothly tran­si­tion­ing be­tween the two.

Di­rectWrite’s sub-pixel ren­der­ing helps to al­le­vi­ate this by doing ex­actly that: glyphs can now start ren­der­ing at that 1.5 pixel dis­tance, or any other point in be­tween. Here you can see the dif­fer­ing space be­tween the ‘V’ and ‘o’, as well as a slight dif­fer­ence be­tween the ‘o’s with Di­rectWrite on the right side, be­cause they are being ren­dered on sub-pixel off­sets:

"Volcano" close-up comparison with GDI and DirectWrite

The dif­fer­ence be­tween an­i­mat­ing with sub-pixel ren­der­ing and with­out is stag­ger­ing when we view it in mo­tion:

"Volcano" animation comparison with GDI and DirectWrite

Prior to Di­rectWrite the nor­mal way to an­i­mate like this was to ren­der to a tex­ture with mono­chrome anti-alias­ing (that is, with­out ClearType), and trans­form the tex­ture while ren­der­ing. The prob­lem with that is the trans­form will in­tro­duce a lot of im­per­fec­tions with­out ex­pen­sive su­per-sam­pling, and of course it won’t be able to use ClearType. With Di­rectWrite you get pixel-per­fect ClearType ren­der­ing every time.

Ap­par­ently WPF 4 is al­ready using Di­rec­t2D and Di­rectWrite to some de­gree, hope­fully there will be high-qual­ity text in­te­grated in Flash’s fu­ture. Fire­fox has also been look­ing at adding Di­rectWrite sup­port, but I haven’t seen any news of We­bkit (Chrome/Sa­fari) or Opera doing the same. It looks like Fire­fox might ac­tu­ally get it in be­fore In­ter­net Ex­plorer. Edit: looks like In­ter­net Ex­plorer 9 will use Di­rectWrite—won­der which will go gold with the fea­ture first?

Di­rec­t2D and Di­rectWrite are in­cluded in Win­dows 7, but Mi­crosoft has back­ported them in the Plat­form Up­date for Win­dows Server 2008 and Win­dows Vista so there’s no rea­son peo­ple who are stick­ing with Vista should be left out. Are there peo­ple stick­ing with Vista?

Windows 7 to support non-OEM CableCARD

TV-on-PC users re­joice! Ca­ble­CARD sup­port is fi­nally com­ing to PC ex­pan­sion cards avail­able through re­tail chan­nels.

Win­dows has long used the Broad­cast Dri­ver Ar­chi­tec­ture (BDA) to com­mu­ni­cate with TV tuner cards, but the folks in charge of Ca­ble­CARD had a major prob­lem with it: there's no DRM sup­port. Be­cause of this they for­bade sell­ing any add-on cards alone, and any TV tuners you could buy would only work with ana­log or Clear­QAM (un­en­crypted) chan­nels, which typ­i­cally means low-def or local chan­nels only. The only way to get Ca­ble­CARD sup­port on a PC was to buy a full OEM setup that in­cluded the tuners.

One of the new fea­tures in Win­dows 7 is the new PBDA (Pro­tected BDA) API which, you guessed it, sup­ports DRM. With PBDA, WDDM, and HDCP, the sig­nal can be pro­tected from the tuner all the way to the mon­i­tor. Mi­crosoft kept quiet and avoided ac­knowl­edg­ing any ques­tions about it dur­ing the test, but many testers spec­u­lated it would be part of a big­ger push from Mi­crosoft to open up Ca­ble­CARD add-on sup­port, and it turns out we were right. I wouldn't be sur­prised to see an­nounce­ments of new hard­ware from Haup­pauge and other tuner man­u­fac­tur­ers.

I watch a lot of TV—usu­ally in the form of a small box in the cor­ner of the screen while I'm cod­ing, so I've got plenty of time. I cur­rently have two Haup­pauge HVR-2250 cards for a total of four tuners. This works great for my local chan­nels like NBC and FOX but there are al­ways some shows I like on cable chan­nels, so I'll be look­ing for­ward to some of the new hard­ware, like Ceton's new 6-tuner Ca­ble­CARD be­he­moth.

Windows 7 is RTMed

After a week of spec­u­la­tion, it's fi­nally been con­firmed. Today, 7600 was signed off as the final RTM build for Win­dows 7.

Fea­ture-wise, Win­dows 7 is a com­pelling evo­lu­tion. It fixes a lot of the is­sues peo­ple had with Vista and adds in a num­ber of great user-, it-, and de­vel­oper-fo­cused fea­tures. Things like Di­rec­t2D and GDI im­prove­ments, User Mode Sched­ul­ing, im­proved NUMA sup­port, im­proved con­cur­rency, SSD sup­port, and im­proved power man­age­ment will all work to­gether to pro­vide higher per­for­mance com­pared to pre­vi­ous OSes. Li­braries, greater mul­ti­me­dia sup­port (such as AAC and AVC), mouse ges­tures, Media Cen­ter, and a com­pletely re­designed taskbar pro­vide a greater user ex­pe­ri­ence. I think this is def­i­nitely the best Win­dows to date -- bet­ter than XP, and bet­ter than Vista.

Test­ing Win­dows 7 was a very frus­trat­ing ex­pe­ri­ence. In con­trast to pre­vi­ous betas where we got a reg­u­lar stream of beta builds to test, in Win­dows 7 we got only two builds, Beta 1 and the RC. A lot of us ex­pe­ri­enced our bugs being set as not re­pro­ducible in in­ter­nal builds, with no way to test if that were true. Worse yet, shortly after the RC came out many of us had a lot of bug re­ports dis­ap­pear when Mi­crosoft told us to not re­port any bugs that didn't cause the OS to blue­screen or fail in­stalling—so there may well be a large num­ber of un­fixed cos­metic and us­abil­ity is­sues in the RTM.

In­stead, Mi­crosoft cre­ated a much smaller team of spe­cial testers called Test Pi­lots who, along with TAP part­ners, would be the ones to get intrim builds and pro­vide the ma­jor­ity of the use­ful feed­back. I'm not sure who this team was made up of, but I would guess they are testers from past betas who chose to de­vote most of their wak­ing hours to test­ing.

This trig­gered some­thing I'd never ex­pected to see—some­what of a re­volt among testers who felt that their feed­back was doing noth­ing. Morale went down, bug re­ports stopped com­ing in, and a lot of heated dis­cus­sion hap­pened be­tween testers. Even the die-hard testers re­al­ized some­thing was wrong, some of them feel­ing the need to mark their dis­cus­sions to dif­fer­en­ti­ate them as a "proud" tester.

Some be­lieve Steve Sinof­sky (who re­placed Jim Allchin as the head of the Win­dows di­vi­sion) is the rea­son for this total re­struc­tur­ing of the Win­dows beta, but as far as I know noth­ing of the sort has been con­firmed. Ei­ther way, with Mi­crosoft seem­ingly frus­trated at our per­for­mance and our frus­tra­tion at not being able to test prop­erly, it feels like we were of lit­tle use this time around de­spite sub­mit­ting a large amount of bugs. I would not be sur­prised if the tech beta gets scrapped en­tirely for Win­dows 8.

User Mode Scheduling in Windows 7

Don’t use threads. Or more pre­cisely, don’t over-use them. It’s one of the first thing fledg­ling pro­gram­mers learn after they start using threads. This is be­cause thread­ing in­volves a lot of over­head. In short, using more threads may im­prove con­cur­rency, but it will give you less over­all through­put as more pro­cess­ing is put into sim­ply man­ag­ing the threads in­stead of let­ting them run. So pro­gram­mers learn to use threads spar­ingly.

When nor­mal threads run out of time, or block on some­thing like a mutex or I/O, they hand off con­trol to the op­er­at­ing sys­tem ker­nel. The ker­nel then finds a new thread to run, and switches back to user-mode to run the thread. This con­text switch­ing is what User Mode Sched­ul­ing looks to al­le­vi­ate.

User Mode Sched­ul­ing can be thought of as a cross be­tween threads and thread pools. An ap­pli­ca­tion cre­ates one or more UMS sched­uler threads—typ­i­cally one for each proces­sor. It then cre­ates sev­eral UMS worker threads for each sched­uler thread. The worker threads are the ones that run your ac­tual code. When­ever a worker thread runs out of time, it is put on the end of its sched­uler thread’s queue. If a worker thread blocks, it is put on a wait­ing list to be re-queued by the ker­nel when what­ever it was wait­ing on fin­ishes. The sched­uler thread then takes the worker thread from the top of the queue and starts run­ning it. Like the name sug­gests, this hap­pens en­tirely in user-mode, avoid­ing the ex­pen­sive user->ker­nel->user-mode tran­si­tions. Let­ting each thread run for ex­actly as long as it needs helps to solve the through­put prob­lem. Work is only put into man­ag­ing threads when ab­solutely nec­es­sary in­stead of in ever smaller time slices, leav­ing more time to run your ac­tual code.

A good side ef­fect of this is UMS threads also help to al­le­vi­ate the cache thrash­ing prob­lems typ­i­cal in heav­ily-threaded ap­pli­ca­tions. For­get­ting your data shar­ing pat­terns, each thread still needs its own stor­age for stack space, proces­sor con­text, and thread-lo­cal stor­age. Every time a con­text switch hap­pens, some data may need to be pushed out of caches in order to load some ker­nel-mode code and the next thread’s data. By switch­ing be­tween threads less often, cache can be put to bet­ter use for the task at hand.

If you have ever had a chance to use some of the more es­o­teric APIs in­cluded with Win­dows, you might be won­der­ing why we need UMS threads when we have fibers which offer sim­i­lar co-op­er­a­tive mul­ti­task­ing. Fibers have a lot of spe­cial ex­cep­tions. There are things that aren’t safe to do with them. Li­braries that rely on thread-lo­cal stor­age, for in­stance, will likely walk all over them­selves if used from within fibers. A UMS thread on the other hand is a full fledged thread—they sup­port TLS and no have no real spe­cial things to keep in mind while using them.

I still wouldn’t count out thread pools just yet. UMS threads are still more ex­pen­sive than a thread pool and the large mem­ory re­quire­ments of a thread still apply here, so things like per-client threads in in­ter­net dae­mons are still out of the ques­tion if you want to be mas­sively scal­able. More likely, UMS threads will be most use­ful for build­ing thread pools. Most thread pools launch two or three threads per CPU to help stay busy when given block­ing tasks, and UMS threads will at least help keep their time slice usage op­ti­mal.

From what I un­der­stand the team be­hind Mi­crosoft’s Con­cur­rency Run­time, to be in­cluded with Vi­sual C++ 2010, was one of the pri­mary forces be­hind UMS threads. They worked very closely with the ker­nel folks to find the most scal­able way to en­able the su­per-par­al­lel code that will be pos­si­ble with the CR.

My Windows Vista/7/8 Wishlist

These are some changes I’ve been try­ing to get made since Vista en­tered beta. Now 7’s beta has begun and still chances look bleak. Maybe I’ll have more luck in 8?

Windows 7 Beta will be free to the public

Not part of the one of the Win­dows 7 beta teams? On Jan­u­ary 9th, the first 2.5 mil­lion peo­ple to visit the Win­dows 7 home­page will be able to down­load the beta for free.

I just got my copy in­stalled a few hours ago, so far I’ve seen a few new fea­tures I like and cou­ple that I’m not sure about. I will blog about specifics as soon as I’m cer­tain what I’m al­lowed to men­tion.

And so, the Windows 7 tech beta begins.

Got my in­vite to the Win­dows 7 tech beta today. The first beta won’t be out until early 2009, but from what I’ve heard the cur­rent in­ter­nal copies of Win­dows 7 are al­ready a pretty good im­prove­ment over Vista, in both per­for­mance and us­abil­ity. Look­ing for­ward to work­ing with all the fine folks I’ve met from the last few betas!