Adaptation/GUID-EF73C56D-AEB1-558B-BAD1-D076BA6EA889.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     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>