|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-EF73C56D-AEB1-558B-BAD1-D076BA6EA889" xml:lang="en"><title>Impact |
|
13 of Data Paging on User Side Code Guide</title><shortdesc>Explains cases in which data paging degrades the performance of |
|
14 user side code and sets out strategies to mitigate these effects. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
15 <section id="GUID-FCD37C40-C547-483C-AB65-B6465955DE70"><title>Purpose</title> <p>Data paging degrades the performance of |
|
16 user side code. This document describes strategies to mitigate these effects. |
|
17 It is intended for application developers whose code uses device drivers. </p> <p><b>Intended Audience:</b> </p> <p>Application developers writing modules |
|
18 which involve device drivers. </p> </section> |
|
19 <section id="GUID-2F31D78F-C2E9-42E1-B489-46B69A2A0AED"><title>Mitigating the impact of data paging on user side code</title> <p>Data |
|
20 paging is a technique which increases the size of virtual RAM by holding data |
|
21 on external media and read into physical RAM when accessed. The technique |
|
22 trades off an increase in available RAM against decreased performance. Developers |
|
23 must allow for the impact on performance and aim to mitigate it by using the |
|
24 practices described in this document. </p> <p>Data paging is mainly a property |
|
25 of processes. Processes can be configured to be paged or unpaged when they |
|
26 are built or put into a ROM image. Threads and the data which they use inherit |
|
27 the data paging configuration of the creating process and that configuration |
|
28 can be modified at the level of the thread or the individual items of data. </p> <p><b>Thread scheduling</b> </p> <p>When a platform uses data paging there is |
|
29 a higher risk of delays, timing-related defects and race conditions. </p> <p>When |
|
30 a thread accesses paged memory, the required page may be paged in (actually |
|
31 in RAM) or paged out (stored in media). If it is paged out, a page fault results, |
|
32 slowing performance by a factor of thousands and sometimes up to a million. |
|
33 The delay can also expose latent race conditions and timing-related defects |
|
34 in existing code: for instance an asynchronous request to a server may appear |
|
35 to complete synchronously, returning control to the client before the request |
|
36 has completed with incorrect behavior as a result. </p> <p>The cure for this |
|
37 problem is to configure data paging when chunks, heaps and threads are created. </p> <p>When |
|
38 creating a thread of class <xref href="GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5.dita"><apiname>RThread</apiname></xref> you can call the creating |
|
39 function <xref href="GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5.dita#GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5/GUID-6C840907-C3F7-34B7-97DB-CEDBA68EA277"><apiname>RThread::Create()</apiname></xref> with an argument of class <xref href="GUID-1D0D14AD-43CF-3B52-AD8D-641F75B8098C.dita"><apiname>TThreadCreateInfo</apiname></xref> as |
|
40 argument. You use an instance of this class to configure the data paging attributes |
|
41 to one of </p> <ul> |
|
42 <li id="GUID-E4F9029C-DEF9-5305-8006-BC56EA509F72"><p> <xref href="GUID-B1A7F7DF-9A43-3C7E-8602-503B7ED5A1A1.dita"><apiname>EUnspecified</apiname></xref> (the |
|
43 thread inherits the paging attributes of the creating process), </p> </li> |
|
44 <li id="GUID-FC939BA1-0822-53AB-B5BC-26CCD4D77075"><p> <xref href="GUID-7B309F53-DF64-389A-8D74-394D9F16E532.dita"><apiname>EPaged</apiname></xref> (the |
|
45 thread will data page its stack and heap), or </p> </li> |
|
46 <li id="GUID-973FCF18-4D8D-56F2-8263-46BF47B179B5"><p> <xref href="GUID-1F1551D0-77AE-33CE-940B-A9E0C4D4881B.dita"><apiname>EUnpaged</apiname></xref> (the |
|
47 thread will not data page its stack and heap). </p> </li> |
|
48 </ul> <p>When creating a chunk of class <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita"><apiname>RChunk</apiname></xref> you can |
|
49 call the creating function <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita#GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07/GUID-EA7C4105-6D64-3F87-83B6-C97DCDEDB94A"><apiname>RChunk::Create()</apiname></xref> with an argument |
|
50 of class <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita"><apiname>TChunkCreateInfo</apiname></xref> as argument. You use an instance |
|
51 of this class to configure the data paging attributes to one of </p> <ul> |
|
52 <li id="GUID-A5BF2717-0814-5CBD-9EA5-296890B633C6"><p> <xref href="GUID-B1A7F7DF-9A43-3C7E-8602-503B7ED5A1A1.dita"><apiname>EUnspecified</apiname></xref> (the |
|
53 chunk inherits the paging attributes of the creating process), </p> </li> |
|
54 <li id="GUID-FAC297A5-27A3-5BA3-94CA-64D548368132"><p> <xref href="GUID-7B309F53-DF64-389A-8D74-394D9F16E532.dita"><apiname>EPaged</apiname></xref> (the |
|
55 chunk will be data paged), or </p> </li> |
|
56 <li id="GUID-86BE6A49-1B9B-59C7-A90B-BF7498138714"><p> <xref href="GUID-1F1551D0-77AE-33CE-940B-A9E0C4D4881B.dita"><apiname>EUnpaged</apiname></xref> (the |
|
57 chunk will not be data paged). </p> </li> |
|
58 </ul> <p>The <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita"><apiname>RChunk</apiname></xref> class also has a function <xref href="GUID-D848C0BA-F931-3F95-96B3-B64133FD5928.dita"><apiname>IsPaged()</apiname></xref> to |
|
59 test whether a chunk is data paged. </p> <p>When creating a chunk heap of |
|
60 class <xref href="GUID-C5D0C7E7-061F-3BA5-AE24-B83237684B01.dita"><apiname>UserHeap</apiname></xref> you can call the creating function <xref href="GUID-C5D0C7E7-061F-3BA5-AE24-B83237684B01.dita#GUID-C5D0C7E7-061F-3BA5-AE24-B83237684B01/GUID-18A6B89B-4844-37E5-B46E-32188760A8C0"><apiname>UserHeap::ChunkHeap()</apiname></xref> with |
|
61 an argument of class <xref href="GUID-3DCB92FB-9C74-3B73-B229-BF7944087EE9.dita"><apiname>TChunkHeapCreateInfo</apiname></xref> as argument. |
|
62 You use an instance of this class to configure the data paging attributes |
|
63 to one of </p> <ul> |
|
64 <li id="GUID-EC970D3F-05F3-52AD-A22C-A512209569A9"><p> <xref href="GUID-B1A7F7DF-9A43-3C7E-8602-503B7ED5A1A1.dita"><apiname>EUnspecified</apiname></xref> (the |
|
65 heap inherits the paging attributes of the creating process), </p> </li> |
|
66 <li id="GUID-66682630-3718-5FE2-AFCC-CB6697DFFC58"><p> <xref href="GUID-7B309F53-DF64-389A-8D74-394D9F16E532.dita"><apiname>EPaged</apiname></xref> (the |
|
67 heap will be data paged), or </p> </li> |
|
68 <li id="GUID-6E922E2B-31EF-58C9-9083-C4590BA11FE2"><p> <xref href="GUID-1F1551D0-77AE-33CE-940B-A9E0C4D4881B.dita"><apiname>EUnpaged</apiname></xref> (the |
|
69 heap will not be data paged). </p> </li> |
|
70 </ul> <p><b>Inter-process |
|
71 communication</b> </p> <p>Data paging impacts on inter-process communication |
|
72 when a non-paged server accesses paged memory passed from a client. If the |
|
73 memory being accessed is not paged in, unpredictable delays may occur, and |
|
74 when the server offers performance guarantees to its clients, all the other |
|
75 clients will be affected as well. There are three separate solutions to this |
|
76 problem: </p> <ul> |
|
77 <li id="GUID-86BB0F84-2660-5682-AA4E-B6922AF54F5F"><p>pinning memory automatically, </p> </li> |
|
78 <li id="GUID-4B6D47CE-9585-5CFF-AFE2-8987FAF9899A"><p>pinning memory as requested |
|
79 by the client, and </p> </li> |
|
80 <li id="GUID-09AC4F78-64A0-5572-AA8A-791176807734"><p>using separate threads |
|
81 for paged and unpaged clients. </p> </li> |
|
82 </ul> <p>Pinning paged memory means paging it into the RAM cache (if it is |
|
83 not already present) and preventing it from being paged out until it is unpinned. </p> <p>You |
|
84 can set a server so that all memory passed to it by a client call gets pinned |
|
85 for the duration of the call. You do so by calling the function <xref href="GUID-E5D22145-1B40-39F4-9242-72B64A0FB29C.dita"><apiname>SetPinClientDescriptors()</apiname></xref> of |
|
86 a <xref href="GUID-8E316AC4-4676-301A-9A23-659E83AA1D1C.dita"><apiname>CServer2</apiname></xref> object after construction but before calling <xref href="GUID-8E316AC4-4676-301A-9A23-659E83AA1D1C.dita#GUID-8E316AC4-4676-301A-9A23-659E83AA1D1C/GUID-3B6AC8A4-251C-39A7-BFB2-30AD454DF590"><apiname>CServer2::Start()</apiname></xref> for |
|
87 the first time. This method is easy but wasteful, as all memory gets pinned |
|
88 not just the data needs and the performance of the paging cache is impacted. |
|
89 Automatic pinning should therefore only be used as a last resort. </p> <p>You |
|
90 can pin specified items of memory at the request of the client by calling |
|
91 the <xref href="GUID-349EE025-F5DB-3430-9BA9-9FBF685F6B07.dita"><apiname>PinArgs()</apiname></xref> function of the <xref href="GUID-4AD02F14-1142-372F-9D11-224595932034.dita"><apiname>TIpcArgs</apiname></xref> class. |
|
92 This is the more efficient method as it allows fine-grained control over what |
|
93 memory is pinned. </p> <p>Separate threads for paged and unpaged clients. </p> <p><b>Thread performance</b> </p> <p>The set of pages accessed by a thread over |
|
94 a given period of time is called its working set. If the working set is paged, |
|
95 the performance of the thread degrades as the working set increases. When |
|
96 working with paged memory it is therefore important to minimise the working |
|
97 set. </p> <p>The main solution to this problem is to choose data structures |
|
98 with high locality, that is data structure residing in single or adjacent |
|
99 pages. An example of this is a preference for arrays rather than linked lists, |
|
100 since arrays are usually in adjacent pages while the elements of linked lists |
|
101 may reside on multiple pages. </p> </section> |
|
102 </conbody><related-links> |
|
103 <link href="GUID-E21E7992-607A-5A49-B022-189ECA9E76D1.dita"><linktext>Code Paging |
|
104 Overview</linktext></link> |
|
105 <link href="GUID-BDB847A2-557A-5902-AA6D-C1AE10D8E493.dita"><linktext>Code Paging |
|
106 Guide</linktext></link> |
|
107 <link href="GUID-B35A70D2-1BC8-51DE-95BF-F315DB394582.dita"><linktext>Demand Paging |
|
108 Overview</linktext></link> |
|
109 </related-links></concept> |