Adaptation/GUID-EF73C56D-AEB1-558B-BAD1-D076BA6EA889.dita
author Graeme Price <GRAEME.PRICE@NOKIA.COM>
Fri, 15 Oct 2010 14:32:18 +0100
changeset 15 307f4279f433
permissions -rw-r--r--
Initial contribution of the Adaptation Documentation.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-EF73C56D-AEB1-558B-BAD1-D076BA6EA889" xml:lang="en"><title>Impact
of Data Paging on User Side Code Guide</title><shortdesc>Explains cases in which data paging degrades the performance of
user side code and sets out strategies to mitigate these effects. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<section id="GUID-FCD37C40-C547-483C-AB65-B6465955DE70"><title>Purpose</title> <p>Data paging degrades the performance of
user side code. This document describes strategies to mitigate these effects.
It is intended for application developers whose code uses device drivers. </p> <p><b>Intended Audience:</b> </p> <p>Application developers writing modules
which involve device drivers. </p> </section>
<section id="GUID-2F31D78F-C2E9-42E1-B489-46B69A2A0AED"><title>Mitigating the impact of data paging on user side code</title> <p>Data
paging is a technique which increases the size of virtual RAM by holding data
on external media and read into physical RAM when accessed. The technique
trades off an increase in available RAM against decreased performance. Developers
must allow for the impact on performance and aim to mitigate it by using the
practices described in this document. </p> <p>Data paging is mainly a property
of processes. Processes can be configured to be paged or unpaged when they
are built or put into a ROM image. Threads and the data which they use inherit
the data paging configuration of the creating process and that configuration
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
a higher risk of delays, timing-related defects and race conditions. </p> <p>When
a thread accesses paged memory, the required page may be paged in (actually
in RAM) or paged out (stored in media). If it is paged out, a page fault results,
slowing performance by a factor of thousands and sometimes up to a million.
The delay can also expose latent race conditions and timing-related defects
in existing code: for instance an asynchronous request to a server may appear
to complete synchronously, returning control to the client before the request
has completed with incorrect behavior as a result. </p> <p>The cure for this
problem is to configure data paging when chunks, heaps and threads are created. </p> <p>When
creating a thread of class <xref href="GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5.dita"><apiname>RThread</apiname></xref> you can call the creating
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
argument. You use an instance of this class to configure the data paging attributes
to one of </p> <ul>
<li id="GUID-E4F9029C-DEF9-5305-8006-BC56EA509F72"><p> <xref href="GUID-B1A7F7DF-9A43-3C7E-8602-503B7ED5A1A1.dita"><apiname>EUnspecified</apiname></xref> (the
thread inherits the paging attributes of the creating process), </p> </li>
<li id="GUID-FC939BA1-0822-53AB-B5BC-26CCD4D77075"><p> <xref href="GUID-7B309F53-DF64-389A-8D74-394D9F16E532.dita"><apiname>EPaged</apiname></xref> (the
thread will data page its stack and heap), or </p> </li>
<li id="GUID-973FCF18-4D8D-56F2-8263-46BF47B179B5"><p> <xref href="GUID-1F1551D0-77AE-33CE-940B-A9E0C4D4881B.dita"><apiname>EUnpaged</apiname></xref> (the
thread will not data page its stack and heap). </p> </li>
</ul> <p>When creating a chunk of class <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita"><apiname>RChunk</apiname></xref> you can
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
of class <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita"><apiname>TChunkCreateInfo</apiname></xref> as argument. You use an instance
of this class to configure the data paging attributes to one of </p> <ul>
<li id="GUID-A5BF2717-0814-5CBD-9EA5-296890B633C6"><p> <xref href="GUID-B1A7F7DF-9A43-3C7E-8602-503B7ED5A1A1.dita"><apiname>EUnspecified</apiname></xref> (the
chunk inherits the paging attributes of the creating process), </p> </li>
<li id="GUID-FAC297A5-27A3-5BA3-94CA-64D548368132"><p> <xref href="GUID-7B309F53-DF64-389A-8D74-394D9F16E532.dita"><apiname>EPaged</apiname></xref> (the
chunk will be data paged), or </p> </li>
<li id="GUID-86BE6A49-1B9B-59C7-A90B-BF7498138714"><p> <xref href="GUID-1F1551D0-77AE-33CE-940B-A9E0C4D4881B.dita"><apiname>EUnpaged</apiname></xref> (the
chunk will not be data paged). </p> </li>
</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
test whether a chunk is data paged. </p> <p>When creating a chunk heap of
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
an argument of class <xref href="GUID-3DCB92FB-9C74-3B73-B229-BF7944087EE9.dita"><apiname>TChunkHeapCreateInfo</apiname></xref> as argument.
You use an instance of this class to configure the data paging attributes
to one of </p> <ul>
<li id="GUID-EC970D3F-05F3-52AD-A22C-A512209569A9"><p> <xref href="GUID-B1A7F7DF-9A43-3C7E-8602-503B7ED5A1A1.dita"><apiname>EUnspecified</apiname></xref> (the
heap inherits the paging attributes of the creating process), </p> </li>
<li id="GUID-66682630-3718-5FE2-AFCC-CB6697DFFC58"><p> <xref href="GUID-7B309F53-DF64-389A-8D74-394D9F16E532.dita"><apiname>EPaged</apiname></xref> (the
heap will be data paged), or </p> </li>
<li id="GUID-6E922E2B-31EF-58C9-9083-C4590BA11FE2"><p> <xref href="GUID-1F1551D0-77AE-33CE-940B-A9E0C4D4881B.dita"><apiname>EUnpaged</apiname></xref> (the
heap will not be data paged). </p> </li>
</ul> <p><b>Inter-process
communication</b> </p> <p>Data paging impacts on inter-process communication
when a non-paged server accesses paged memory passed from a client. If the
memory being accessed is not paged in, unpredictable delays may occur, and
when the server offers performance guarantees to its clients, all the other
clients will be affected as well. There are three separate solutions to this
problem: </p> <ul>
<li id="GUID-86BB0F84-2660-5682-AA4E-B6922AF54F5F"><p>pinning memory automatically, </p> </li>
<li id="GUID-4B6D47CE-9585-5CFF-AFE2-8987FAF9899A"><p>pinning memory as requested
by the client, and </p> </li>
<li id="GUID-09AC4F78-64A0-5572-AA8A-791176807734"><p>using separate threads
for paged and unpaged clients. </p> </li>
</ul> <p>Pinning paged memory means paging it into the RAM cache (if it is
not already present) and preventing it from being paged out until it is unpinned. </p> <p>You
can set a server so that all memory passed to it by a client call gets pinned
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
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
the first time. This method is easy but wasteful, as all memory gets pinned
not just the data needs and the performance of the paging cache is impacted.
Automatic pinning should therefore only be used as a last resort. </p> <p>You
can pin specified items of memory at the request of the client by calling
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.
This is the more efficient method as it allows fine-grained control over what
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
a given period of time is called its working set. If the working set is paged,
the performance of the thread degrades as the working set increases. When
working with paged memory it is therefore important to minimise the working
set. </p> <p>The main solution to this problem is to choose data structures
with high locality, that is data structure residing in single or adjacent
pages. An example of this is a preference for arrays rather than linked lists,
since arrays are usually in adjacent pages while the elements of linked lists
may reside on multiple pages. </p> </section>
</conbody><related-links>
<link href="GUID-E21E7992-607A-5A49-B022-189ECA9E76D1.dita"><linktext>Code Paging
Overview</linktext></link>
<link href="GUID-BDB847A2-557A-5902-AA6D-C1AE10D8E493.dita"><linktext>Code Paging
Guide</linktext></link>
<link href="GUID-B35A70D2-1BC8-51DE-95BF-F315DB394582.dita"><linktext>Demand Paging
Overview</linktext></link>
</related-links></concept>