<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>システム開発</title><link>http://blogs.wankuma.com/jitta/category/409.aspx</link><description>システム開発に関する、設計やデバッグなど</description><managingEditor>はなおか じった</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>はなおか じった</dc:creator><title>FxCop その2</title><link>http://blogs.wankuma.com/jitta/archive/2012/03/30/263449.aspx</link><pubDate>Fri, 30 Mar 2012 23:34:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2012/03/30/263449.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/263449.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2012/03/30/263449.aspx#Feedback</comments><slash:comments>93</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/263449.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/263449.aspx</trackback:ping><description>&lt;p class="p"&gt;&lt;A href="http://blogs.wankuma.com/jitta/archive/2012/03/18/260357.aspx"&gt;前のエントリ&lt;/a&gt;で、aetosさんからコメントを頂きました。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;一般論として、CA1063 や CA1816 を抑止するのは不穏な臭いが。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="p"&gt;はい、確かに、その通りです。&lt;/p&gt;
&lt;p class="p"&gt;抑止したい、具体的なコードを示します。まず、MSDN のドキュメントから。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="quoteSource"&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx" title="⇒microsoft.com" class="outerLink"&gt;アンマネージ リソースをクリーンアップするための Finalize および Dispose の実装&lt;/a&gt;（msdn）より：&lt;/p&gt;
&lt;p&gt;Dispose メソッド名のカスタマイズ&lt;/p&gt;
&lt;p&gt;場合によっては、Dispose ではなく、ドメイン固有の名前を付ける方が適切なこともあります。たとえば、ファイルのカプセル化では、メソッド名として Close を使用した方が適切です。この場合は、Dispose をプライベートに実装し、Dispose を呼び出すパブリックな Close メソッドを作成します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;この、「Dispose メソッド名のカスタマイズ」を行います。新規にクラス ライブラリ プロジェクトを作成し、次のコードを書きます。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;// Dispose メソッド名をカスタマイズしたクラス
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Practice16
{
    public class Class1 : IDisposable
    {
        private IntPtr handle;
        private Stream file;

        ~Class1()
        {
            this.Dispose(false);
        }

        public void Open(string fname)
        {
            // ハンドルを獲得
            this.handle = Marshal.AllocHGlobal(1024);
            file = new FileStream(fname, FileMode.Open);
        }

        public void Close()
        {
            ((IDisposable)this).Dispose();
        }

        //public void Close()
        //{
        //    this.Dispose(true);
        //    GC.SuppressFinalize(this);
        //}

        protected virtual void Dispose(bool disposing)
        {
            if (disposing == true)
            {
                // マネージ オブジェクトで
                // 破棄が必要なものを破棄
                file.Close();
            }

            // ハンドルを破棄
            Marshal.FreeHGlobal(this.handle);
            handle = IntPtr.Zero;
        }

        #region IDisposable メンバ

        void IDisposable.Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        //void IDisposable.Dispose()
        //{
        //    this.Close();
        //}

        #endregion
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;このコードを FxCop に通すと、次のエラーが出ます。&lt;/p&gt;
&lt;div style="margin-left:2em; margin-right:2em;"&gt;
&lt;dl&gt;
 &lt;dt&gt;CA2210&lt;/dt&gt;
 &lt;dd&gt;アセンブリに署名していないため。&lt;/dd&gt;
 &lt;dt&gt;CA1014&lt;/dt&gt;
 &lt;dd&gt;アセンブリが CLS 互換性があるとマークされていないため。&lt;/dd&gt;
 &lt;dt&gt;CA1063&lt;/dt&gt;
 &lt;dd&gt;&lt;code&gt;IDisposable&lt;/code&gt; インターフェイスを実装しながら &lt;code&gt;public void Dispose()&lt;/code&gt; メソッドがないため。&lt;/dd&gt;
 &lt;dt&gt;CA2122&lt;/dt&gt;
 &lt;dd&gt;&lt;code&gt;Dispose(bool)&lt;/code&gt; メソッドで &lt;code&gt;Marshal.FreeHGlobal(IntPtr)&lt;/code&gt; メソッドを使用しているが、セキュリティ チェックが行われていないため。&lt;/dd&gt;
 &lt;dt&gt;CA2122&lt;/dt&gt;
 &lt;dd&gt;&lt;code&gt;Open(String)&lt;/code&gt; メソッドで &lt;code&gt;Marshal.AllocHGlobal(int)&lt;/code&gt; メソッドを使用しているが、セキュリティ チェックが行われていないため。&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p class="p"&gt;CA1816 は、&lt;code&gt;Close()&lt;/code&gt; メソッドと &lt;code&gt;Dispose&lt;/code&gt; メソッドの明示実装をコメントアウトしているような実装にしていたからで、これは、直しました。&lt;/p&gt;
&lt;p class="p"&gt;この様に、メソッド名をカスタマイズすると、FxCop はかなり強い警告を表示します。明示実装があるんだから堪忍して欲しい。それとも、&lt;code&gt;Close()&lt;/code&gt; と &lt;code&gt;Dispose()&lt;/code&gt; の両方を置く？&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/263449.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>FxCop と StyleCop</title><link>http://blogs.wankuma.com/jitta/archive/2012/03/18/260357.aspx</link><pubDate>Sun, 18 Mar 2012 19:47:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2012/03/18/260357.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/260357.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2012/03/18/260357.aspx#Feedback</comments><slash:comments>1349</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/260357.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/260357.aspx</trackback:ping><description>&lt;p class="p"&gt;内容の非道い C# のコードを見ていて、何とかするために何ができるか考えた。結局、「これこれのコードで指摘が出るから直した方が良い」というのが、理由付けが簡単かな？と考え、FxCop を適用することにした。それを調べている途中で、StyleCop の事を知った。それらを使うための準備。&lt;/p&gt;
&lt;p class="p"&gt;FxCop は、IL を解析して、様々なルールに沿っているかどうかをチェックするツール。IL を解析するので、VB だろうが C# だろうがドンとこい。しかし、IL を解析するので、指摘事項がコードのどこに該当するのか、分かり難い。しかし、ツール上に出てくる指摘に対する詳細が書かれたウェブ ページは日本語化されている。&lt;/p&gt;
&lt;p class="p"&gt;StyleCop は、C# のコードを解析して、ルールに沿っているかどうかをチェックするツール。コードを解析するので、C# しか対応していない。また、指摘事項に対するコードを探すのが容易。しかし、今のところ英語しかない（有志による翻訳はある）。&lt;/p&gt;
&lt;p class="p"&gt;まず、FxCop。Visual Studio の Premium エディション、Ultimate エディションの場合、VS のインストールで一緒にインストールされる（多分）。Professional 以下のエディションの場合、Windows SDK 7.1 をダウンロードしてくる。&lt;a class="outerLink" title="⇒microsoft.com" href="http://www.microsoft.com/download/en/details.aspx?id=8279"&gt;ウェブ インストーラのダウンロード ページ&lt;/a&gt;からインストーラをダウンロードする。SDK インストール後、スタートメニューより「Microsoft Windows SDK v7.1→Tools→Install Microsoft FXCop」を選択して、FxCop のインストーラを実行する。&lt;/p&gt;
&lt;p class="p"&gt;適用されるルールは以下の通り。一部注釈が付いているのは、手持ちのプロジェクトで指摘された項目。&lt;/p&gt;
&lt;pre&gt;Design Rules
 CA1012: Abstract types should not have constructors
 CA2210: Assemblies should have valid strong names
   アセンブリは、正しい厳密名を持つべきです。
 CA1040: Avoid empty interfaces
 CA1005: Avoid excessive parameters on generic types
 CA1020: Avoid namespaces with few types
 CA1021: Avoid out parameters
   out パラメータを使わないようにします。
 CA1010: Collections should implement generic interface
 CA1011: Consider passing base types as parameters
 CA1009: Declare event handlers correctly
 CA1050: Declare types in namespaces
 CA1026: Default parameters should not be used
 CA1019: Define accessors for attribute arguments
 CA1031: Do not catch general exception types
   Exception あるいは SystemException をキャッチしてはいけません。
 CA1047: Do not declare protected members in sealed types
 CA1000: Do not declare static members on generic types
 CA1048: Do not declare virtual members in sealed types
 CA1051: Do not declare visible instance fields
   外部からアクセス可能なインスタンス フィールドを宣言しないようにします。
 CA1002: Do not expose generic lists
 CA1061: Do not hide base class methods
 CA1006: Do not nest generic types in member signatures
 CA1046: Do not overload operator equals on reference types
 CA1045: Do not pass types by reference
   ref パラメータを使うことは避けます。
 CA1065: Do not raise exceptions in ubexpected locations
 CA1028: Enum storage should be Int32
 CA1038: Enumerators should be strongly typed
 CA1008: Enums should have zero value
   列挙型は 0 の値を含むようにしましょう。
 CA1064: Exceptions should be public
 CA1004: Generic methods should provide type parameter
 CA1035: ICollection implementations have strongly typed members
 CA1063: Implement IDisposable collectly
 CA1032: Implement standard exception constructors
 CA1023: Indexers should not be multidimensional
 CA1033: Interface methods should be callable by child types
 CA1039: Lists are stongly typed
 CA1016: Mark assemblies with AssemblyVersionAttribute
 CA1014: Mark assenblies with CLSCompliantAttribute
   アセンブルを CLSCompliantAttribute でマークしましょう。
 CA1017: Mark assenblies with ComVisibleAttribute
 CA1018: Mark attributes with AttributeUsageAttribute
 CA1027: Mark enum with FlagAttribute
   列挙型を FlagsAttribute でマークしましょう。
 CA1059: Members should not expose certain concrete types
 CA1060: Move P/Invokes to NativeMethods class
   プラットフォーム呼び出しは、NativeMethods クラスに集約しましょう。
 CA1034: Nested types should not be visible
   型をグルーピングするためにネストした型を使わないようにしましょう。
 CA1013: Overload operator equals on overloading add and subtract
 CA1036: Override methods on comparable types
 CA1044: Properies should not be write only
 CA1041: Provide ObsoleteAttribute message
 CA1025: Replace repetitive arguments with params array
 CA1052: Static holder types should be sealed
 CA1053: Static holder types should not have constructors
 CA1057: String URI overloads call System.Uri overloads
 CA1058: Types should not extend certain base types
 CA1001: Types that own disposable fields should be disposable
 CA1049: Types that own native respources should be disposable
 CA1054: URI parameters should not be strings
 CA1056: URI properties should not bee strings
 CA1055: URI return values should not be strings
 CA1030: Use events where appropriate
 CA1003: Use generic event handler instances
 CA1007: Use generic where appropriate
 CA1043: Use integral or string argument for indexers
 CA1024: Use properties where appropriate

Globalization Rules
 CA1301: Avoid duplicate accelerators
 CA1302: Do not gardcode locale specific strings
 CA1308: Normalize strings to uppercase
 CA1306: Set locale for data types
 CA1304: Specify CultureInfo
 CA1305: Specify IFormatProvider
   IFormatProvider を受け入れるオーバーロードを利用するようにします。
 CA2101: Specify marshaling for P/Invoke string arguments
   文字列引数に対してマーシャリングを指定します。
 CA1300: Specify MessageBoxOptions
   MessageBox のオプションは明示するようにします。
 CA1307: Specify StringComparison
   StringComaprison パラメーターを指定するようにします。
 CA1309: Use ordinal StringComparison

Interoperability Rules
 CA1403: Auto layout types should not be COM visible
 CA1406: Avoid Int64 arguments for Visual Basic 6 client
 CA1413: Avoid non-public fields in COM visible value type
 CA1402: Avoid overloads in COM visible types
 CA1407: Avoid static members in COM visible types
 CA1404: Call GetLastError immediately after P/Invoke
 CA1410: COM registration methods should be matched
 CA1411: COM registration methods should not be visible
 CA1405: COM visible type base types should be COM visible
 CA1409: COM visible types should be creatable
 CA1415: Declare P/Invokes correctly
 CA1408: Do not use AutoDual ClassInterfaceType
 CA1414: Mark boolean P/Invoke arguments with MarshalAs
 CA1412: Mark ComSource interfaces as IDispatch
 CA1400: P/Invoke entry points should exist
 CA1401: P/Invokes should not be visible

Mobility Rules
 CA1600: Do not use idle process priority
 CA1601: Do not use timers that prevent power state changes
   省電力設定を妨げるようなタイマーを使用しません。
   1秒より短い時間を指定してください。

Naming Rules
 CA1702: Compound words should be cased collectly
 CA1700: Do not name enum values 'Reserved'
 CA1712: Do not prefix enum values with type name
 CA1713: Events should not have before or after prefix
 CA1714: Flags enums should have plural names
 CA1709: Identifiers should be cased correctly
   識別子は、正しく大文字小文字を使用します。
   ※ 日本語識別子を使用する場合は OFF
 CA1704: Identifiers should be spelled correctly
   識別子は正しいスペルを使用します。
   ※ 日本語識別子を使用する場合は OFF
 CA1708: Identifiers should differ by more than case
 CA1715: Identifiers should have correct prefix
 CA1710: Identifiers should have correct suffix
 CA1720: Identifiers should not contain type names
 CA1707: Identifires should not contain underscores
   識別子にはアンダースコアを含まないようにします。
 CA1722: Identifiers should not have incorrect prefix
 CA1711: Identifiers should not have incorrect suffix
 CA1716: Identifiers should not match keywords
 CA1717: Only FlagsAttribute enum should have plural names
 CA1725: Parameter names should match base declaration
 CA1719: Parameter names should not match member names
 CA1721: Property names should not match get methods
 CA1701: Resource string compound words should be cased correctly
   ※ 日本語識別子を使用する場合は OFF
 CA1703: Resource strings should be spelled correctly
 CA1724: Type names should not match namespaces
 CA1726: Use preferred terms
   適切な用語を使用します。

Performance Rules
 CA1809: Avoid excessive locals
 CA1811: Avoid uncalled private code
   呼び出されていない private なメソッドを使用しません。
 CA1812: Avoid uninstantiated internal classes
 CA1813: Avoid unsealed attributes
 CA1823: Avoid unused private fields
   参照されていない private なフィールドを使用しません。
 CA1800: Do not cast unnecessarily
   不必要にキャストしません。
 CA1810: Initialize reference type static fields inline
 CA1824: Mark assemblies with NeutralResourcesLanguageAttribute
 CA1822: Mark members as static
   メンバーを static としてマークします。
 CA1815: Override equals and operator equals on value types
   構造体では euquals および operator equals をオーバーライドします。
 CA1814: Prefer jagged arrays over multidimensional
 CA1819: Properties should not returns arrays
   プロパティでは配列を返さないようにします。
 CA1821: Remove empty finalizers
 CA1804: Remove unused locals
   使用していないローカル変数を削除します。
 CA1820: Test for empty strings using string length
 CA1802: Use literals where appropriate

Portability Rules
 CA1901: P/Invoke declarations should be portable
   P/Invoke の宣言は、移植性を考慮しなければなりません。
 CA1903: Use only API from targeted framework
 CA1900: Value type fields should be portable

Security Rules
 CA2116: APTCA methods should only call APTCA methods
 CA2117: APTCA types should only extend APTCA base types
 CA2105: Array fields should not be read only
 CA2115: Call GC.KeepAlive when using native resources
 CA2102: Catch non-CLSCompliant exceptions in general handlers
 CA2104: Do not declare read only mutable reference types
 CA2122: Do not indirectly expose methods with link demands
   セキュリティ上の要求があるメンバーを呼び出すメソッドについて、セキュリティ要求が設定されていません。
 CA2114: Method security should be a superset of type
 CA2111: Pointers should not be visible
   パブリックな System.IntPtr 型のフィールドが読み取り専用ではありません。
 CA2108: Review declarative security on value types
 CA2107: Review deny and permit only usage
 CA2103: Review imperative security
 CA2118: Review SupressUnmanagedCodeSecurityAttribute usage
 CA2109: Review visible event handlers
 CA2119: Seal methods thar satisfy private interfaces
 CA2106: Secure asserts
 CA2120: Secure serialization constructors
 CA2112: Secured types should not expose fields
 CA2121: Static constructors should be private
 CA2126: Type link demands require inheritance demands
 CA2124: Wrap vulnerable finaly clauses in outer try

Security Transparency Rules
 CA2132: Default constructors must be at least as critical as base type default constructors
 CA2133: Delegates must bind to methods with consistent transparancy
 CA2135: Level2 assemblies should not cintain LinkDemands
 CA2136: Members should not have conflicting transparency annotations
 CA2134: Methods must keep consistent transparency when overriding vase methods
 CA2123: Override link demands should be identical to base
 CA2130: Security critical constants should be transparent
 CA2131: Security critical types may not participate in type equivalance
 CA2147: Transparent code may not use security asserts
 CA2140: Transparent code must not reference security critical items
 CA2142: Transparent code should not be protected with LinkDemands
 CA2144: Transparent code should not load assemblies from byte arrays
 CA2139: Transparent methods may not use the HandleProcessCorruptingExceptions attribute
 CA2137: Transparent menthods must contain only verifiable IL
 CA2149: Transparent methods must not call into native code
 CA2138: Transparent methods must not call methods with the SuppressUnmanagedCodeSecurity attibute
 CA2141: Transparent methods must not satisfy LinkDemands
 CA2145: Transparent methods should not be decorated with the SuppressUnmanagedCodeSecurity attribute
 CA2143: Transparent methods should not use security demands
 CA2146: Types must be at least as critical as their base types and interfaces

Usage Rules
 CA2243: Attribute string literals should parase correctly
 CA2236: Call base class methods on ISerializable types
 CA1816: Call GC.SuppressFinalize correctly
   GC.SuppressFinalize メソッドの呼び出しが正しくありません。
   Dispose メソッドでは GC.SupressFilaze メソッドを呼び出します。
   IDispose インターフェイスを実装しないクラスでは GC.SupressFinalize メソッドを呼び出しません。
 CA2227: Collection properties should be read only
 CA2213: Disposable fields should be disposed
 CA2216: Disposable types should declare finalizer
 CA2214: Do not call overridable methods in constructors
 CA2222: Do not decrease inherited member visibility
 CA1806: Do not ignore method results
 CA2217: Do not mark enums with FlagsAttribute
 CA2212: Do not mark serviced components with WebMethod
 CA2219: Do not raise exceptions in exception clauses
 CA2201: Do not raise reserved exception types
 CA2228: Do not ship unreleased resource formats
 CA2221: Finalizers should be protected
 CA2220: Finalizers shoul call base class finalizer
 CA2240: Implement ISerializable correctly
 CA2229: Implement serialization constructors
 CA2238: Implement serialization methods correctly
 CA2207: Initialize value type static fields inline
 CA2208: Instantiate argument exceptions correctly
 CA2235: Mark all non-serializable fields
 CA2237: Mark ISerializable types with SerializableAttribute
 CA2232: Mark Windows Forms entry points with STAThread
 CA2223: Members should differ by more than return value
 CA2211: Non-constant fields should not be visible
 CA2233: Operations should not overflow
 CA2225: Operator overloads have named alternates
   演算子オーバーロードは、名前づけられた別名を使用するようにします。
 CA2226: Operator should have symmetrical overlods
 CA2231: Overloda operator equals on overriding ValueType.Equals
 CA2224: Override Equals on overloading operator equals
 CA2218: Override GetHashCode on overriding Equals
 CA2234: Pass System.Uri objects instead of string
 CA2239: Provide deserialization methods for optional fields
 CA2200: Rethrow to preserve stack details
 CA1801: Review unused parameters
 CA2242: Test for NaN correctly
 CA2205: Use managed equivalents of Win32 API
 CA2230: Use params for variable arguments
&lt;/pre&gt;
&lt;p class="p"&gt;ちょっと参ったのは、IDisposable インターフェイスを実装して、Dispose メソッドの名称を変更しようとした場合。変更すると、CA1063, CA1816 あたりが指摘される。これを抑止する方法。アセンブリ単位で抑止したい場合、FxCop 上で「Exclude」を選ぶ。指摘ひとつひとつについて「理由」を入力する場合（こちらをお勧め）、次の方法。&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;Visual Studio で、プロジェクトのプロパティを開く。&lt;/li&gt;
 &lt;li&gt;[ビルド]ページを開く。&lt;/li&gt;
 &lt;li&gt;「条件付きコンパイル シンボル」に、「CODE_ANALYSIS」を追加する。（FxCop の検出を抑止するために必要）&lt;/li&gt;
 &lt;li&gt;FxCop 上でエラーをポイントし、右クリックする。&lt;/li&gt;
 &lt;li&gt;「Copy As」→「SuppressMessage」を選択する。&lt;/li&gt;
 &lt;li&gt;Visual Sttudio で、該当するコード（メソッド）の上に「貼り付け」する。&lt;/li&gt;
 &lt;li&gt;「SupprressMessage」に波線が引かれる場合、[Shilt]+[Alt]+[F10] で、名前空間を追加する。&lt;/li&gt;
 &lt;li&gt;カッコ内に「, Justification = "抑止する理由"」を追加する。（追加しない場合、StyleCop で指摘される）&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;p class="p"&gt;次、StyleCop。こちらは、ビルド後に StyleCop が自動実行されるようにする。&lt;/p&gt;
&lt;p class="p"&gt;インストーラを、&lt;a class="outerLink" title="⇒codeplex.com" href="http://stylecop.codeplex.com/"&gt;CodePlex のページ&lt;/a&gt;からダウンロードする。こちらは、FxCop の様な二度実行はない。Visual Studio へは、プロジェクト単位に登録することになる。一部、バージョンに依存するところがあるが、ここでは v4.7 で説明する。&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;ファイル ヘッダーを用意する。または、ファイル ヘッダーのチェックを適用しない（後述）。必要最小限のヘッダーは、次の通り。
  &lt;div style="font-size: 80%; margin-left: 20px;"&gt;&lt;pre&gt;// &amp;lt;copyright file="ファイル名" company="会社名"&amp;gt;
//     ここに独自のコピーライト メッセージを書く
// &amp;lt;/copyright&amp;gt;
  &lt;/pre&gt;&lt;/div&gt;
 &lt;/li&gt;
 &lt;li&gt;プロジェクト ファイル（.csproj）をテキスト エディタで開く。&lt;/li&gt;
 &lt;li&gt;&amp;lt;Project&amp;gt; 要素の中に、次の１行を追加する。（既にある Import の下が良い）
  &lt;div style="font-size: 80%; margin-left: 20px;"&gt;
   &amp;lt;Import Project="$(ProgramFiles)\MSBuild\StyleCop\v4.7\StyleCop.targets" /&amp;gt;
  &lt;/div&gt;
 &lt;/li&gt;
 &lt;li&gt;ソリューション エクスプローラーでプロジェクトを右クリックして、StyleCop の設定を行う。&lt;/li&gt;
 &lt;li&gt;[Company Information]タブを開き、「Comapny Name」と「Copyright」を入力する。これがファイル ヘッダーに指定されていないと指摘される。&lt;/li&gt;
 &lt;li&gt;[Rules]タブを開き、設定を行う。&lt;br&gt;
  ひとつのプロジェクトで設定をすると、「Settings.StyleCop」という名前のファイルが出来る。これを、全てのプロジェクトのひとつ上のディレクトリにコピーしておく。そうすると、各プロジェクトでは[Setting Files]タブを開き、「Mege with settings file found in parent folder」に設定するだけでよい。&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;適用されるルールは以下の通り。一部注釈が付いているのは、手持ちのプロジェクトで指摘された項目。★は、デフォルトでチェックされている項目。□は、デフォルトでチェックされていない項目。○は、チェックを外した項目。●は、チェックした項目。&lt;/p&gt;
&lt;pre&gt;C# [○Analyze designer files][○Analyze generated files]
  ※ デザイナーなど、自動生成ファイルは適用外とする。
★Documentation Rules
 ★Element Documentation [●Ignore privates][□ignore internals][★include fields]
   ※ private メンバーについてはドキュメント化の対象外とする。
  ★SA1600: Elements must be documented
    エレメントはドキュメントを持たなければなりません。
  ★SA1601: Partial elements must be documented
  ★SA1602: Enumeration item must be documented
  ★SA1603: Documentation must contain valid XML
    ドキュメントは正当な XML を含んでいなければなりません。
  ★SA1604: Element documentation must have summary
  ★SA1605: Partial element documentation must have summary text
  ★SA1606: Element documentation must have summary text
  ★SA1607: Partial element documentation must have summary text
  ★SA1608: Element documentation must not have default summary
  □SA1609: Property documentation must have value
  □SA1610: Property documentation must have value text
  ★SA1611: Element parameters must be documented
    エレメントのパラメータはドキュメント化されていなければなりません。
  ★SA1612: Element parameter documentation must match element parameters
    エレメントのパラメータのドキュメントは、エレメントのパラメータと一致していなければなりません。
  ★SA1613: Element parameter documentation must declare parameter name
  ★SA1614: Element parameter documentation must have text
    エレメントのパラメータのドキュメントは、テキストを含んでいなければなりません。
  ★SA1615: Element return value must be documented
    エレメントの戻り値はドキュメント化されていなければなりません。
  ★SA1616: Element return value documentation must have text
    エレメントの戻り値のドキュメントは、テキストを含んでいなければなりません。
  ★SA1617: Void return value must not be documented
    戻り値がない場合はドキュメント化されていてはなりません。
  ★SA1618: Generic type parameters must be documented
  ★SA1619: Generic type parameters must be documented partial class
  ★SA1620: Generic type parameter documentation must match type parameters
  ★SA1621: Generic type parameter documentation must declare parameter name
  ★SA1622: Generic type parameter documentation must have text
  ○SA1623: Property summary documentation must match accessors
    プロパティの要約ドキュメントは、アクセッサーと一致していなければなりません。
    ※ 日本語とは一致しないため、外す。
  ★SA1624: Property summary documentation must omit set accessor with restricted access
  ★SA1625: Element documentation must not be copied and pasted
  ★SA1626: Single-line comments must not use documentation style slashes
    一行コメントは、XML ドキュメント形式のスラッシュを使用してはいけません。
  ★SA1627: Documentation text must not be empty
  □SA1628: Documentation text must begin with a capital letter
  □SA1629: Documentation text must end with a period
  ○SA1630: Documentation text must contain whitespace
    ドキュメントの中にホワイトスペースが含まれていません。
    ※ 日本語とは一致しないため、外す。
  ★SA1631: Documentation must meet character percentage
  □SA1632: Documentation text must meer minimum character length
  ○SA1642: Constructor summary documentation must begin with standard text
    コンストラクタの要約ドキュメントは、標準テキストで始めなければなりません。
    ※ 日本語とは一致しないため、外す。
  ○SA1643: Destructor summary documentation must begin with standard text
    デストラクタの要約ドキュメントは、標準テキストで始めなければなりません。
    ※ 日本語とは一致しないため、外す。
  ★SA1644: Documentation headers must not contain blank-lines
  ★SA1646: Included documentation XPath does not extist
  ★SA1647: Included node does not contain valid file and path
  ★SA1648: Inherit doc must be used with inheriting class
 ★File Headers
  ★SA1633: File must have header
    ファイル ヘッダーを含まなければなりません。
  ★SA1634: File header must show copyright
  ★SA1635: File header must have Copyright text
  ★SA1637: File header must contain file name
  ★SA1638: File header file name documentation must match file name
  □SA1639: File header must have summary
  ★SA1640: File header must have valid company text
  ★SA1649: File header file name documentation must match type name

★Layout Rules
 ★Curly Blakets
  ★SA1500: Curly brackets for multi-line statements must not share line
    複文のための中括弧は違う行に配置します。
  ★SA1501: Statement must not be on single-line
  ★SA1502: Element must not be on single-line
  ★SA1503: Curly brackets must not be omitted
    中括弧を忘れてはいけません。
  ★SA1504: All accessors must be multi-line or single-line
 ★Line Spacing
  ★SA1505: Opening curly brackets must not be followed by blank line
    開き中括弧に空行を続けてはいけません。
  ★SA1506: Element documentation headers must not be followed by blank line
  ★SA1507: Code must not contain multiple blank lines in a row
    複数行からなる空行を含んではいけません。
  ★SA1508: Closing curly blackets must not be preceded by blank line
    閉じ中括弧の前が空行であってはいけません。
  ★SA1509: Opening curly brackets must not be preceded by blank line
  ★SA1510: Chained statement blocks must not be preceded by blank line
  ★SA1511: While do footer must not be preceded by blank line
  ★SA1512: Single-line comment must not be followed by blank line
  ★SA1513: Closing curly bracket must be followed by blank line
    閉じ中括弧の後は空行でなければなりません。（括弧や catch などのキーワードは除く）
  ★SA1514: Element documentation header must be preceded by blank line
    エレメントのドキュメントは空行に続かなければなりません。
  ★SA1515: Single line comment must be preceded by blank line
    一行コメントは空行に続かなければなりません。（一時的にコメントアウトしたい場合は '////' を使用します。）
  ★SA1516: Elements must be separated by blank line
    エレメント間は空行で分けます。
  ★SA1517: Code must not contain blank lines at start of file
  ★SA1518: Code must not contain blank lines at end of file

★Maintainability Rules
 ★Access Modifiers
  ★SA1400: Access modifier must be declared
  ★SA1401: Fields must be private
    フィールドは private であるべきです。
 ★Debug Text
  ★SA1404: Code analysis suppression must have justification
  ★SA1405: Debug assert must provide message text
  ★SA1406: Debug fail must provide message text
 ★File Contents
  ★SA1402: File may only contain a single class
  ★SA1403: File may only contain a single namespace
 ★Parenthesis
  ★SA1119: Statement must not use unnecessary parenthesisparenthesis
    不必要な括弧を含んではいけません。
  ★SA1407: Arithmetic expressions must declare precedence
  ★SA1408: Conditional expressions must declare precedence
  ★SA1410: Remoce delegate parenthesis when possible
  ★SA1411: Attribute constructor must not use unnecessary parenthesis
 ★Removable Code
  ★SA1409: Remove unnecessary code

★Naming Rules
  ★SA1300: Element must begin with upper case letter
    エレメントは大文字から始めなければなりません。
    ※日本語エレメント名を使用するときは無視します。
  ★SA1301: Element must begin with lower case letter
  ★SA1302: Interface names must begin with 'I'
  ★SA1303: Const field names must begin with upper case letter
  ★SA1304: Non private readonly fields must begin with upper case letter
  ★SA1305: Field names must not use hangarian notation
    フィールド名にはハンガリアン記法を使用しません。
  ★SA1306: Field names must begin with lower case letter
    フィールド名は小文字から始めなければなりません。
    ※日本語フィールド名を使用するときは無視します。
  ★SA1307: Accessible fields must begin with upper case letter
    アクセス制限によって、フィールド名は大文字から始めます。
  ★SA1308: Variable names must not be prefixed
  ★SA1309: Field names must not begin with underscore
    フィールド名をアンダースコアから始めてはいけません。
  ★SA1310: Field names must not contain underscode
    フィールド名にアンダースコアを含めてはいけません。

★Ordering Rules [○Include generated code]
 ★Element Order
  ○SA1200: Using directives must be placed within namespace
    using ディレクティブは namespace の中に書かなければなりません。
    ※ 初期設定と異なるため、適用除外とする。
  ★SA1201: Elements must appear in the correct order
    エレメントは一定の順序で書かれていなければなりません。
     フィールド
     コンストラクター
     ファイナライザー
     デリゲート
     イベント
     列挙体
     インターフェイス
     プロパティ
     インデクサー
     メソッド
     構造体
     内部クラス
  ★SA1202: Element must be orderd by access
    エレメントは、アクセス可能性の順に書かれていなければなりません。
     public
     internal
     protected internal
     protected
     private
  ★SA1203: Constants must appear before fields
  ★SA1204: Static elements must appear vefore instace elements
  ★SA1206: Declaration keywords must follow order
    宣言文のキーワードは、一定の順序で書かれていなければなりません。
     アクセス修飾子
     static
     その他のキーワード
  ★SA1207: Protected must come before internal
  ★SA1212: Property accessors must follow order
    プロパティのアクセッサーは、get, set の順に書かれていなければなりません。
  ★SA1213: Event accessors must follow order
    イベントのアクセッサーは、add, remove の順に書かれていなければなりません。
 ★Using Directives
  ★SA1208: System using directices must be placed before other using directives
    System の using ディレクティブは、他の要素よりも先に書かれていなければなりません。
    ※ コンテキスト メニューから起動するコマンド「using の整理」→「using の並べ替え」を使用します。
  ★SA1209: Using alias directives must be placed after other using directives
  ★SA1210: Using directives mmust be orderd alphabetically by namespace
    ※ コンテキスト メニューから起動するコマンド「using の整理」→「using の並べ替え」を使用します。
  ★SA1211: Using alias directives must be ordered alphabetically by alias name

★Readability Rules
 ★Comments
  ★SA1120: Commrnts must contain text
 ★Member Access
  ★SA1100: Do not prefix calls with base unless local implementation exists
  ★SA1101: Prefix local calls with this
 ★Method Parameter Placement
  ★SA1110: Opening parenthesis must be on declaration line
  ★SA1111: Closing parenthesis must be on line of last parameter
  ★SA1112: Closing parenthesis must ve on line of opening parenthesis
  ★SA1113: Comma must be on same line as previous parameter
  ★SA1114: Parameter list must follow declaraion
  ★SA1115: Parameter must follow comma
  ★SA1116: Split parameters must start on line after separate lines
  ★SA1117: Parameters must be on same line or separate lines
  ★SA1118: Parameter must not span multiple lines
 ★Query Expressions
  ★SA1102: Query clause must follow previous clause
  ★SA1103: Query clauses must be on separate lines or all on one line
  ★SA1104: Query clause must begin on new line when previous clause spans multiple line
  ★SA1105: Query clauses spanning multiple line must begin on own line
 ★Regions
  ★SA1123: Do not place regions within elements
  □SA1124: Do not use regions
 ★Statements
  ★SA1106: Code must not contain empty statements
  ★SA1107: Code must not contain multiple statements on one line
  ★SA1108: Block staements must not contain embedded comments
  ★SA1109: Block statements must not contain embedded regions
 ★Strings
  ★SA1122: Use string empty for empty string
 ★Types
  ○SA1121: Use builtin type alias
    型の完全な名称よりも、ビルトインで用意されている別名を使いましょう。
    ※ Int16 など、完全な名称を使う方が幅が明記できるため、見やすい場合もあるため、無効とする。
  ★SA1125: Use shorthand for nullable types

★Spacing Rules
  ★SA1000: Keywords must be spaced correctly
  ★SA1001: Commas must be spaced correctly
  ★SA1002: Semicolons must be spaced correctly
  ★SA1003: Symbols must be spaced correctly
  ★SA1004: Documentation lines must begin with single space
  ★SA1005: Single line comments must begin with single space
  ★SA1006: Preprocessor keywords must not be preceded by space
  ★SA1007: Operator keyword must be followed by space
  ★SA1008: Opening parenthesis must be spaced correctly
  ★SA1009: Closing parenthesis must be spaced correctly
  ★SA1010: Opening square brackets must be spaced correctly
  ★SA1011: Closing square brackets must be spaced correctly
  ★SA1012: Opening curly brackets must be spaced correctly
  ★SA1013: Closing culy brackets must be spaced correctly
  ★SA1014: Opening generic brackets must be spaced correctly
  ★SA1015: Closing generic brackets must be spaced correctly
  ★SA1016: Opening attribute brackets must be spaced correctly
  ★SA1017: Closing attribute brackets must be spaced correctly
  ★SA1018: Nullable type symbols must not be preceded by space
  ★SA1019: MemberAccess symbols must be spaced correctly
  ★SA1020: Increment decrement symbols must be spaced correctly
  ★SA1021: Negative signs must be spaced correctly
  ★SA1022: Positive sign must be spaced correctly
  ★SA1023: Dereference and access of symbols must be spaced correctly
  ★SA1024: Colons must bespaced correctly
  ★SA1025: Code must not cintain multiple wtitespace in a row
  ★SA1026: Code must not contain space after new keyword in implicitly typed array allocation
  ○SA1027: Tabs must not be used
    TAB 文字を使用してはいけません。
    ※ TAB と SPACE については意見が二分するので適用外とする。
&lt;/pre&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/260357.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>カーナビと、18年前の案件</title><link>http://blogs.wankuma.com/jitta/archive/2010/02/24/186406.aspx</link><pubDate>Wed, 24 Feb 2010 22:48:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2010/02/24/186406.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/186406.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2010/02/24/186406.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/186406.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/186406.aspx</trackback:ping><description>&lt;P class=p&gt;昨年の夏、滋賀へ行くのに「カーナビが欲しいなぁ」と思っていたら、Joshin で安価になっていたので購入しました。よくあることですが、直後に新製品が出ました。それは本題ではなくて。&lt;/P&gt;
&lt;P class=p&gt;昨年、新しい道路が出来ました。それまで細い道だったのが、少し通りやすくなっています。その道は、今まで緩いカーブに繋がっていたところに、新たに真っ直ぐ付けられています。「入る」の一画目しかなかったところに、二画目が出来た、みたいなイメージで。地図は2007年くらいのものなので、まだ道が出来ていません。&lt;/P&gt;
&lt;P class=p&gt;この道を走っているとき、ふと気がつくと、新しい道を走っているのに、カーナビ上では古い道を走っていることになっていました。しばらくして、「おや？間違えた」みたいに、ふっと、表示が変わる。おそらく、道なりに進んでいると思って、計算した値との違いは「誤差」だという判断だったのでしょう。&lt;/P&gt;
&lt;P class=p&gt;で、18年くらい前の案件の話。当時、私は救急向けの、地図情報システムに関わっていました。消防署や警察で、電話がかかってきたとき、住所を聞いて、その住所近くの地図を表示します。表示する地図は、ゼンリンの住宅地図を200DPI、または400DPI で取り込んで、表示します（ゼンリンより、コンピューターに取り込む許可を得て実施）。その中で、ある県警から出された要求。&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;GPS を搭載したパトカーを、本署で表示している地図上にアイコンにて示す。このとき、GPS では誤差が大きい（今より精度が低かった）ので、「この道を走っているだろう」と思われる道路をブリンク表示させる。&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=p&gt;パトカーが何台あるかわからないし、どれくらいの&amp;#8220;誤差&amp;#8221;があって、どの程度の&amp;#8220;予想誤り&amp;#8221;が許容されるのか。突き詰めていけば面白かったのかもしれないけど、即、「無理」と断ったのでした。&lt;/P&gt;
&lt;P class=p&gt;今では、そういうシステムも、無理ではないのかもしれない。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/186406.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>処理並列は、処理速度向上をもたらすのか？</title><link>http://blogs.wankuma.com/jitta/archive/2010/02/05/185818.aspx</link><pubDate>Fri, 05 Feb 2010 23:42:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2010/02/05/185818.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/185818.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2010/02/05/185818.aspx#Feedback</comments><slash:comments>29</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/185818.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/185818.aspx</trackback:ping><description> &lt;h1&gt;処理並列は、必ず処理速度が向上するのか&lt;/h1&gt;
&lt;div id="contents"&gt;
&lt;div id="main"&gt;
&lt;div class="inner"&gt;
&lt;div id="NWrelart:Body"&gt;
&lt;div id="article"&gt;

 &lt;p&gt;　3つのアルゴリズムを並列化して、並列化によってどのように処理効率が向上するのか、検証します。&lt;/p&gt;
&lt;div id="p1"&gt;
&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;　CPUは、コンピューターの頭脳です。単純に考えると、頭脳が2つあれば、1つの時と比べて、同じ時間でたくさんのことを考えることができそうです。10年ほど前、Intel製プロセッサーPentium IIの頃から、1枚のボードに複数のCPUを載せて高速化する試みがなされました。Intel製CPUでは2ユニットまででしたが、SUN Microsystems製のコンピューターでは、もっとたくさんのユニットを載せることができていました。今では、CPU自体に複数の「コア」を載せ、1ユニットで同時に別々のことを実行できるようになっています。&lt;/p&gt;
&lt;p&gt;　ハードウェアが、同時に複数のことを実行できるようになったため、ソフトウェアもそれに対応する必要が出てきました。本記事では、昨今あちらこちらで声高に繰り返される、「並列処理化すれば速くなる」に疑問を持ったため、それを検証することにします。&lt;/p&gt;
&lt;h2&gt;対象読者&lt;/h2&gt;
&lt;p&gt;　なんといっても、並列処理化に興味のある方が対象です。特に、「並列化すれば速くなる」と、単純に思い込んでいる方に、読んでもらいたいと思います。&lt;/p&gt;
&lt;p&gt;　本記事では、Visual C++ 2008を元に、基本的にC言語によるコードにより、検証を行います。よって、ある程度のC言語の知識があるとよいでしょう。しかし、処理は日本語で説明をするようにしますので、C言語の文法を知っている必要はありません。&lt;/p&gt;
&lt;h2&gt;必要な環境&lt;/h2&gt;
&lt;p&gt;　本記事を読む分には、特別な環境を必要としません。&lt;/p&gt;
&lt;p&gt;　本記事で紹介するコード例を試すには、Visual Studio C++ 2008を使用します。また、実際に差異を見るためには、タスクマネージャーで複数のCPU使用履歴が表示されるPCが必要です。&lt;/p&gt;
&lt;h2&gt;並列処理化の有用性を検証する&lt;/h2&gt;
&lt;h3&gt;どうやって検証するか&lt;/h3&gt;
&lt;p&gt;　まず、検証方法を設計します。どういう仮説があって、その仮説が正しいことを証明するためには、どの様な実験から、どの様な結果が出ればよいのか。これらを明らかにしておかなければ「検証」ではなく、「観察」になってしまいます。&lt;/p&gt;
&lt;p&gt;　本記事は「並列化すれば速くなる」という仮定を検証します。このために、いくつかのアルゴリズムについてコードを作成します。そのコードを、Open MPによってマルチスレッド化します。シングル、マルチスレッドで実行完了までにかかる時間を計測し、それぞれマルチスレッドによってどれくらい実行時間が短縮できたかを算出します。短縮時間を比べることで、マルチスレッド化がどのようなな時にも有効なのか、調査することとします。&lt;/p&gt;
&lt;/div&gt;
&lt;div id="p2"&gt;
&lt;h3&gt;アルゴリズム1：素数を求める&lt;/h3&gt;
&lt;p&gt;　素数とはなんでしょうか。1と、その数以外の数では割り切ることができない数です。では、どうやってこれを求めましょうか。2からその数の手前までの数で順番に割ってみて、割りきれる数があるかどうか調べます。つまり、11が素数かどうか調べるには、2、3、4、5、6、7、8、9、10で割り切れるかどうかを調べます。コードで示すと次のようになります。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;素数を判別するコード例&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
// 素数かどうか、判別する
// 戻り値：0&amp;hellip;素数ではない / 0以外&amp;hellip;素数
int IsPrimeNumber(const int 調べる数)
{
  for (int i = 2; i &amp;lt; 調べる数; ++i) {
      if (調べる数 % i == 0) {
          return 0;
      }
  }
  return 1;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　素数を求めたい範囲について、&lt;code&gt;for&lt;/code&gt;文でループします。それぞれの数についてこの判別関数を通すことで、素数かどうかを調べます。とりあえず、この関数では「素数の数」だけ返すようにします。処理を並列化することの効率を測定するので、コンソールへの出力は行いません。コンソールへの出力がシリアル化される、コンソール出力は遅い処理である、というのが理由です。求めた素数は配列へ格納します。配列を動的に拡張すると、メモリを確保するという並列化できない要素が出てくるため、呼び出し側で確保しておくこととします。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;ある数までの素数を求めるコード例&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
int GetPrimeNumbers(const int この数まで, int *素数配列 = NULL, const int 配列数 = 0)
{
    int count = 0;
    for (int i = 2; i &amp;lt;= この数まで; ++i) {
        if (IsPrimeNumber(i) != 0) {
            ++count;
            if (素数配列 != NULL &amp;amp;&amp;amp; index &amp;lt; 配列数) {
                素数配列[i] = i;
            }
        }
    }
    return count;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　これで「ある数までの素数の数を求めるコード」ができました。では、このコードが正しいかどうか、検証します。コードによって、1～20までの素数の数を求めさせます。これくらいなら、自分で計算もできるでしょう。その結果とつきあわせます。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;素数（の数）を求めるコードを検証するコード&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
#include &amp;quot;stdafx.h&amp;quot;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;omp.h&amp;gt;
int IsPrimeNumber(const int 調べる数) をここに
int GetPrimeNumbers(const int この数まで, int *素数配列 = NULL, const int 配列数 = 0) をここに
int _tmain(int argc, _TCHAR* argv[])
{
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(2) &amp;lt;&amp;lt; &amp;quot;個/2&amp;hellip;1\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(3) &amp;lt;&amp;lt; &amp;quot;個/3&amp;hellip;2\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(4) &amp;lt;&amp;lt; &amp;quot;個/4&amp;hellip;2\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(5) &amp;lt;&amp;lt; &amp;quot;個/5&amp;hellip;3\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(6) &amp;lt;&amp;lt; &amp;quot;個/6&amp;hellip;3\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(7) &amp;lt;&amp;lt; &amp;quot;個/7&amp;hellip;4\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(8) &amp;lt;&amp;lt; &amp;quot;個/8&amp;hellip;4\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(9) &amp;lt;&amp;lt; &amp;quot;個/9&amp;hellip;4\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(10) &amp;lt;&amp;lt; &amp;quot;個/10&amp;hellip;4\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(11) &amp;lt;&amp;lt; &amp;quot;個/11&amp;hellip;5\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(12) &amp;lt;&amp;lt; &amp;quot;個/12&amp;hellip;5\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(13) &amp;lt;&amp;lt; &amp;quot;個/13&amp;hellip;6\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(14) &amp;lt;&amp;lt; &amp;quot;個/14&amp;hellip;6\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(15) &amp;lt;&amp;lt; &amp;quot;個/15&amp;hellip;6\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(16) &amp;lt;&amp;lt; &amp;quot;個/16&amp;hellip;6\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(17) &amp;lt;&amp;lt; &amp;quot;個/17&amp;hellip;7\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(18) &amp;lt;&amp;lt; &amp;quot;個/18&amp;hellip;7\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(19) &amp;lt;&amp;lt; &amp;quot;個/19&amp;hellip;8\n&amp;quot;;
    std::cout &amp;lt;&amp;lt; GetPrimeNumbers(20) &amp;lt;&amp;lt; &amp;quot;個/20&amp;hellip;8\n&amp;quot;;
    return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;実行結果&lt;/div&gt;
&lt;pre class="src"&gt;
1個/2&amp;hellip;1
2個/3&amp;hellip;2
2個/4&amp;hellip;2
3個/5&amp;hellip;3
3個/6&amp;hellip;3
4個/7&amp;hellip;4
4個/8&amp;hellip;4
4個/9&amp;hellip;4
4個/10&amp;hellip;4
5個/11&amp;hellip;5
5個/12&amp;hellip;5
6個/13&amp;hellip;6
6個/14&amp;hellip;6
6個/15&amp;hellip;6
6個/16&amp;hellip;6
7個/17&amp;hellip;7
7個/18&amp;hellip;7
8個/19&amp;hellip;8
8個/20&amp;hellip;8
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　コードが正しいことが検証できました。これを基に、マルチスレッド化のためのコードを追加します。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;GetPrimeNumbersをマルチスレッド化する&lt;/div&gt;
&lt;pre class="prettyprint"&gt;&lt;span style="color:red;"&gt;
int GetPrimeNumbersParallel(const int この数まで, int *素数配列 = NULL, const int 配列数 = 0)
{
    int count = 0;
    #pragma omp parallel for reduction(+:count)
    for (int i = 2; i &amp;lt;= この数まで; ++i) {
        if (IsPrimeNumber(i) != 0) {
            ++count;
            if (素数配列 != NULL &amp;amp;&amp;amp; i &amp;lt; 配列数) {
                素数配列[i] = i;
            }
        }
    }
    return count;
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　これも、検証しておきます。&lt;code&gt;GetPrimeNumbers&lt;/code&gt;がシングルスレッドで動作することと、&lt;code&gt;GetPrimeNumbersParallel&lt;/code&gt;がマルチスレッドで動作しているかを確認します。確認を行う土台が、確認を行う目的にとって正しいことを確認しておかないと、何を確認しているのかわからなくなります。&lt;/p&gt;
&lt;p&gt;　次のように&lt;code&gt;_tmain&lt;/code&gt;関数を書き換え、実行します。実行中、タスクマネージャーの［プロセス］タブで実行しているプロセスのスレッド数と、CPU使用率を見ます。スレッド数は、初期状態では表示されていないので、［表示］メニューから［列の選択］を選び、一覧から［スレッド数］を探してチェックします。シングルスレッドの方は、スレッド数が&amp;ldquo;1&amp;rdquo;、CPU使用率は&amp;ldquo;(100/CPU数)％&amp;rdquo;であることを確認します。また、マルチスレッドの方は、スレッド数が&amp;ldquo;CPU数&amp;rdquo;、CPU使用率が&amp;ldquo;100％&amp;rdquo;であることを確認します。もし、マルチスレッド側のスレッド数が&amp;ldquo;1&amp;rdquo;の場合、プロジェクトのプロパティで、［構成プロパティ］&amp;rarr;［C/C++］&amp;rarr;［言語］を開き、［OpenMPサポート］が「はい(/openmp)」になっていることを確認してください。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;シングルスレッドであることを確認する&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
int _tmain(int argc, _TCHAR* argv[])
{
    GetPrimeNumbers(300000);
    return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;マルチスレッドであることを確認する&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
int _tmain(int argc, _TCHAR* argv[])
{
    GetPrimeNumbersParallel(300000);
    return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="p3"&gt;
&lt;h3&gt;アルゴリズム2：FizzBuzz問題&lt;/h3&gt;
&lt;p&gt;　FizzBuzz問題はご存知ですね。1から任意の数までについて出力します。しかし、3の倍数の時は「Fizz」、5の倍数の時は「Buzz」と出力します。これを単純にコード化すると、次のようになります。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;FizzBuzz問題のコード&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
void FizzBuzz(const int この数まで)
{
    for (int i = 1; i &amp;lt;= この数まで; ++i) {
        if (i % 15 == 0) {
            std::cout &amp;lt;&amp;lt; &amp;quot;FizzBuzz &amp;quot;;
        } else if (i % 3 == 0) {
            std::cout &amp;lt;&amp;lt; &amp;quot;Fizz &amp;quot;;
        } else if (i % 5 == 0) {
            std::cout &amp;lt;&amp;lt; &amp;quot;Buzz &amp;quot;;
        } else {
            std::cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot; &amp;quot;;
        }
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　しかし、こうすると、出力結果でコンソールが大変なことになります。また、このように出力すると並列化したときに「実行順」が問題になります。そのため、ここでは文字列領域を確保し、そこに入れていくことにします。これも動作の検証をして、並列化したコードも作ります。ここでは動作検証は省きますが、実際にやってみる場合は、しっかり検証してください。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;FizzBuzz問題のコード（文字列格納型）&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
#define FIZZBUZZMAX 5000000
char FB結果[FIZZBUZZMAX][12];
void FizzBuzz(const int この数まで)
{
    for (int i = 1; i &amp;lt;= この数まで; ++i) {
        if (i % 15 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;FizzBuzz&amp;quot;);
        } else if (i % 3 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;Fizz&amp;quot;);
        } else if (i % 5 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;Buzz&amp;quot;);
        } else {
            sprintf_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;%d&amp;quot;, i);
        }
    }
}
void FizzBuzzParallel(const int この数まで)
{
    #pragma omp parallel for
    for (int i = 1; i &amp;lt;= この数まで; ++i) {
        if (i % 15 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;FizzBuzz&amp;quot;);
        } else if (i % 3 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;Fizz&amp;quot;);
        } else if (i % 5 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;Buzz&amp;quot;);
        } else {
            sprintf_s(FB結果[i], sizeof(FB結果[i]), &amp;quot;%d&amp;quot;, i);
        }
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;アルゴリズム3：バブルソート&lt;/h3&gt;
&lt;p&gt;　3つ目のアルゴリズムは、バブルソートです。&lt;/p&gt;
&lt;p&gt;　バブルソートのアルゴリズムをおさらいしましょう。配列に数値が並んでいます。この数値を、小さい順に並べるとします。まず、配列の1番後ろと、その1つ手前を比べます。後ろにある方が大きければ、入れ替えます。次に、後ろから2番目と、その1つ手前を比べます。そして、1つ手前の方が大きければ入れ替えます。これを、最初の要素まで繰り返します。最初までくると、「1番小さい数値」が決定します。そこで今度は、「2番目に小さい数値」を決定すべく、また1番後ろから比較を繰り返します。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;バブルソートのコード&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
#define BSORTNUM 100000
int BS配列[BSORTNUM];
void BubbleSort(int* 対象配列, const int 配列数)
{
    for (int 決定済み数 = 0; 決定済み数 &amp;lt; 配列数; ++決定済み数) {
        for (int y = 配列数 - 1; y &amp;gt; 決定済み数; --y) {
            if (対象配列[y] &amp;lt; 対象配列[y - 1]) {
                int tmp = 対象配列[y];
                    対象配列[y] = 対象配列[y - 1];
                    対象配列[y - 1] = tmp;
            }
        }
    }
}
void BubbleSortParallel(int* 対象配列, const int 配列数)
{&lt;span style="color:red;"&gt;
    for (int 決定済み数 = 0; 決定済み数 &amp;lt; 配列数; ++決定済み数) {
        #pragma omp parallel for
        for (int y = 配列数 - 1; y &amp;gt; 決定済み数; --y) {&lt;/span&gt;
            if (対象配列[y] &amp;lt; 対象配列[y - 1]) {
                int tmp = 対象配列[y];
                対象配列[y] = 対象配列[y - 1];
                対象配列[y - 1] = tmp;
            }
        }
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　さて、これも検証しておきます。すると、並列化した方で、結果がおかしいことが分かります。以下の結果は、BSORTNUMを100として検証したときの結果です。「BS配列」は、BSORTNUM～1で初期化するようにしました。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;バブルソートの検証をするコード&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
void Shuffle(int *対象配列, const int 配列数)
{
    for (int i = 配列数 - 1; i &amp;gt;= 0; --i) {
        対象配列[i] = 配列数 - i;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    for (int i = 0; i &amp;lt; 1; ++i) {
        Shuffle(BS配列, BSORTNUM);
        std::cout &amp;lt;&amp;lt; &amp;quot;ソート前\n&amp;quot;;
        for (int i = 0; i &amp;lt; BSORTNUM; ++i) {
            std::cout &amp;lt;&amp;lt; BS配列[i] &amp;lt;&amp;lt; &amp;quot;\t&amp;quot;;
        }
        std::cout &amp;lt;&amp;lt; &amp;quot;\n----------\nソート後\n&amp;quot;;
        BubbleSortParallel(BS配列, BSORTNUM);
    }
    for (int i = 0; i &amp;lt; BSORTNUM; ++i) {
        std::cout &amp;lt;&amp;lt; BS配列[i] &amp;lt;&amp;lt; &amp;quot;\t&amp;quot;;
    }
    return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;実行結果（一例）&lt;/div&gt;
&lt;pre class="src" style="text-decoration:line-through;"&gt;
ソート前
88      25      18      83      54      90      79      2       49      73
94      92      13      14      97      52      96      75      27      38
100     39      61      40      59      24      7       26      29      30
42      31      23      55      53      36      37      91      11      98
62      74      43      66      71      46      47      95      58      16
51      45      76      6       99      17      19      12      82      60
33      41      35      64      84      5       67      22      68      70
50      72      10      65      80      86      77      44      9       78
81      85      93      32      87      69      8       1       89      3
20      15      4       63      48      56      28      21      34      57
----------
ソート後
1       2       3       4       4       5       6       7       8       9
10      11      12      13      14      15      16      17      18      19
20      21      21      22      23      24      25      26      27      28
29      30      31      33      34      35      36      37      38      39
40      41      42      43      44      45      46      47      48      49
88      50      51      83      54      90      79      52      53      73
94      92      55      56      97      57      96      75      58      59
100     60      61      62      63      64      65      66      67      68
69      70      71      72      74      76      77      91      78      98
80      81      82      84      86      87      89      95      93      99
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;　検証するクセを付けておいてよかったでしょ？&lt;/p&gt;
&lt;p&gt;　実は、バブルソートのアルゴリズムは、並列化に向いていません。複数の並列に行われる処理が、同じ領域を書き換えようとするためです。上の実行結果では、「4」が2回現れています。代わりに、32がなくなっています。「4」のことを除くと50までは正しいように思われますが、51以上は並び方がおかしいです。これは「&lt;code&gt;対象配列[y]&lt;/code&gt;」と「&lt;code&gt;対象配列[y-1]&lt;/code&gt;」の比較入れ替えで、複数のスレッドが、&lt;code&gt;y&lt;/code&gt;の値が同じところを操作しようとしたためです。&lt;/p&gt;
&lt;p&gt;&lt;span style="color:red;"&gt;　これを防ぐために、バブルソートのアルゴリズムについて、調べなければなりません。先に書いているように、バブルソートでは、検査をする場所を、順番に調べなければなりません。単純に並列化すると、実行する順序は保障されません。実行順序が保障されない、すなわち検査する順序が前後すると、並びがおかしくなるケースが発生します。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:red;"&gt;　OpenMPでは、&lt;code&gt;ordered&lt;/code&gt;句と&lt;code&gt;ordered&lt;/code&gt;ディレクティブを使うことで、順番に実行される事を保障します。まず、&lt;code&gt;for&lt;/code&gt;ディレクティブに&lt;code&gt;ordered&lt;/code&gt;句を指定して、「順番に実行されるブロックがある」ことを指示します。次に、&lt;code&gt;ordered&lt;/code&gt;ディレクティブによって、順番に実行されるブロックを明示します。&lt;/span&gt;&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;バブルソートのコード（順序づけとマーク）&lt;/div&gt;
&lt;pre class="prettyprint"&gt;&lt;span style="color:red;"&gt;
void BubbleSortParallel(int* 対象配列, const int 配列数)
{
    for (int 決定済み数 = 0; 決定済み数 &amp;lt; 配列数; ++決定済み数) {
        #pragma omp parallel for ordered
        for (int y = 配列数 - 1; y &amp;gt; 決定済み数; --y) {
            #pragma omp ordered
            if (対象配列[y] &amp;lt; 対象配列[y - 1]) {
                int tmp = 対象配列[y];
                対象配列[y] = 対象配列[y - 1];
                対象配列[y - 1] = tmp;
            }
        }
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;実行結果（一例）&lt;/div&gt;
&lt;pre class="src" style="text-decoration:line-through;"&gt;
ソート前
63      2       3       100     5       81      16      82      86      53
11      1       13      14      34      35      58      74      19      40
8       22      23      24      73      18      27      28      9       30
55      56      33      76      99      12      98      4       26      90
68      37      57      44      67      95      47      48      32      69
51      52      78      54      80      38      94      17      59      60
72      49      43      64      65      66      45      41      50      70
88      7       25      84      77      15      62      10      36      92
6       21      83      61      85      29      87      42      89      96
91      20      93      79      46      31      97      71      39      75
----------
ソート後
1       2       3       4       5       6       7       8       9       10
11      12      13      14      15      16      17      18      19      20
21      22      23      24      25      26      27      28      29      30
31      32      33      34      35      36      37      38      39      40
41      42      43      44      45      46      47      48      49      50
51      52      53      54      55      56      57      58      59      60
61      62      63      64      65      66      67      68      69      70
71      72      73      74      75      76      77      78      79      80
81      82      83      84      85      86      87      88      89      90
91      92      93      94      95      96      97      98      99      100
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="p4"&gt;
&lt;p&gt;　さて、一通りできました。ここまでのコードを、もう一度掲示しておきます。&lt;/p&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;検証コード（全体）&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
#include "stdafx.h"
#include &amp;lt;Windows.h&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;math.h&amp;gt;
#include &amp;lt;omp.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/timeb.h&amp;gt;
#include &amp;lt;time.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#define PRIMENUMBERS    500000
#define FIZZBUZZMAX     30000000
#define BSORTNUM        30000
#define CHECKNUM        5
char FB結果[FIZZBUZZMAX][12];
int BS配列[BSORTNUM];
int PR配列[PRIMENUMBERS];
#define TmToSec(X) ((X).time + (X).millitm / 1000.0)
#define DiffTmSec(START, STOP) (TmToSec(STOP) - TmToSec(START))
// 素数かどうか、判別する
// 戻り値：0&amp;#8230;素数ではない / 0以外&amp;#8230;素数
int IsPrimeNumber(const int 調べる数)
{
    for (int i = 2; i &amp;lt; 調べる数; ++i) {
        if (調べる数 % i == 0) {
            return 0;
        }
    }
    return 1;
}
int IsPrimeNumberFast(const int 調べる数)
{
    if (調べる数 == 2) { return 1;}
    if (調べる数 % 2 == 0) { return 0;}
    int limit = (int) sqrt((double)調べる数);
    for (int i = 3; i &amp;lt; limit; i += 2) {
        if (調べる数 % i == 0) {
            return 0;
        }
    }
    return 1;
}
int GetPrimeNumbers(const int この数まで,
    int *素数配列 = NULL, const int 配列数 = 0)
{
    int count = 0;
    for (int i = 2; i &amp;lt;= この数まで; ++i) {
        if (IsPrimeNumber(i) != 0) {
            ++count;
            if (素数配列 != NULL &amp;amp;&amp;amp; i &amp;lt; 配列数) {
                素数配列[i] = i;
            }
        }
    }
    return count;
}
int GetPrimeNumbersParallel(const int この数まで,
    int *素数配列 = NULL, const int 配列数 = 0)
{
    int count = 0;
    #pragma omp parallel for reduction(+:count) //schedule(guided)
    for (int i = 2; i &amp;lt;= この数まで; ++i) {
        if (IsPrimeNumber(i) != 0) {
            ++count;
            if (素数配列 != NULL &amp;amp;&amp;amp; i &amp;lt; 配列数) {
                素数配列[i] = i;
            }
        }
    }
    return count;
}
void FizzBuzz(const int この数まで)
{
    for (int i = 1; i &amp;lt;= この数まで; ++i) {
        if (i % 15 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), "FizzBuzz");
        } else if (i % 3 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), "Fizz");
        } else if (i % 5 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), "Buzz");
        } else {
            sprintf_s(FB結果[i], sizeof(FB結果[i]), "%d", i);
        }
    }
}
void FizzBuzzParallel(const int この数まで)
{
    #pragma omp parallel for
    for (int i = 1; i &amp;lt;= この数まで; ++i) {
        if (i % 15 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), "FizzBuzz");
        } else if (i % 3 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), "Fizz");
        } else if (i % 5 == 0) {
            strcpy_s(FB結果[i], sizeof(FB結果[i]), "Buzz");
        } else {
            sprintf_s(FB結果[i], sizeof(FB結果[i]), "%d", i);
        }
    }
}
void BubbleSort(int* 対象配列, const int 配列数)
{
    for (int 決定済み数 = 0; 決定済み数 &amp;lt; 配列数; ++決定済み数) {
        for (int y = 配列数 - 1; y &amp;gt; 決定済み数; --y) {
            if (対象配列[y] &amp;lt; 対象配列[y - 1]) {
                int tmp = 対象配列[y];
                対象配列[y] = 対象配列[y - 1];
                対象配列[y - 1] = tmp;
            }
        }
    }
}
void BubbleSortParallel(int* 対象配列, const int 配列数)
{
    for (int 決定済み数 = 0; 決定済み数 &amp;lt; 配列数; ++決定済み数) {
        #pragma omp parallel for ordered
        for (int y = 配列数 - 1; y &amp;gt; 0; --y) {
            #pragma omp ordered
            if (対象配列[y] &amp;lt; 対象配列[y - 1]) {
                int tmp = 対象配列[y];
                対象配列[y] = 対象配列[y - 1];
                対象配列[y - 1] = tmp;
            }
        }
    }
}
void Shuffle(int *対象配列, const int 配列数)
{
    for (int i = 配列数 - 1; i &amp;gt;= 0; --i) {
        対象配列[i] = 配列数 - i;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    struct _timeb startTm, stopTm;    // ストップウォッチ用
    std::cout &amp;lt;&amp;lt; "素数の数を求める範囲\t" &amp;lt;&amp;lt; PRIMENUMBERS &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "FizzBuzz を求める範囲\t" &amp;lt;&amp;lt; FIZZBUZZMAX &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "Bubble Sort の要素数\t" &amp;lt;&amp;lt; BSORTNUM &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "繰り返し回数\t" &amp;lt;&amp;lt; CHECKNUM &amp;lt;&amp;lt; "\n\n";
    /**/
    double bsSeri = 0.0;
    for (int i = 0; i &amp;lt; CHECKNUM; ++i) {
        Shuffle(BS配列, BSORTNUM);
        _ftime_s(&amp;amp;startTm);
        BubbleSort(BS配列, BSORTNUM);
        _ftime_s(&amp;amp;stopTm);
        std::cout &amp;lt;&amp;lt; "BubbleSort シリアル\t"
            &amp;lt;&amp;lt; DiffTmSec(startTm, stopTm) &amp;lt;&amp;lt; " sec.\n";
        bsSeri += DiffTmSec(startTm, stopTm);
    }
    /**/
    double bsPall = 0.0;
    for (int i = 0; i &amp;lt; CHECKNUM; ++i) {
        Shuffle(BS配列, BSORTNUM);
        _ftime_s(&amp;amp;startTm);
        BubbleSortParallel(BS配列, BSORTNUM);
        _ftime_s(&amp;amp;stopTm);
        std::cout &amp;lt;&amp;lt; "BubbleSort パラレル\t"
            &amp;lt;&amp;lt; DiffTmSec(startTm, stopTm) &amp;lt;&amp;lt; " sec.\n";
        bsPall += DiffTmSec(startTm, stopTm);
        for (int j = 0; j &amp;lt; BSORTNUM - 1; ++j) {
            if (BS配列[j] + 1 != BS配列[j+1]) {
                std::cout &amp;lt;&amp;lt; "wrong:" &amp;lt;&amp;lt; j &amp;lt;&amp;lt; "\n";
            }
        }
    }
    /**/
    double fbSeri = 0.0;
    for (int i = 0; i &amp;lt; CHECKNUM; ++i) {
        _ftime_s(&amp;amp;startTm);
        FizzBuzz(FIZZBUZZMAX);
        _ftime_s(&amp;amp;stopTm);
        std::cout &amp;lt;&amp;lt; "FizzBuzz シリアル\t"
            &amp;lt;&amp;lt; DiffTmSec(startTm, stopTm) &amp;lt;&amp;lt; " sec.\n";
        fbSeri += DiffTmSec(startTm, stopTm);
    }
    double fbPall = 0.0;
    for (int i = 0; i &amp;lt; CHECKNUM; ++i) {
        _ftime_s(&amp;amp;startTm);
        FizzBuzzParallel(FIZZBUZZMAX);
        _ftime_s(&amp;amp;stopTm);
        std::cout &amp;lt;&amp;lt; "FizzBuzz パラレル\t"
            &amp;lt;&amp;lt; DiffTmSec(startTm, stopTm) &amp;lt;&amp;lt; " sec.\n";
        fbPall += DiffTmSec(startTm, stopTm);
    }
    /**/
    int cnt;
    double pnSeri = 0.0;
    for (int i = 0; i &amp;lt; CHECKNUM; ++i) {
        _ftime_s(&amp;amp;startTm);
        cnt = GetPrimeNumbers(PRIMENUMBERS);
        _ftime_s(&amp;amp;stopTm);
        std::cout &amp;lt;&amp;lt; "素数 シリアル " &amp;lt;&amp;lt; cnt &amp;lt;&amp;lt; "個\t"
            &amp;lt;&amp;lt; DiffTmSec(startTm, stopTm) &amp;lt;&amp;lt; " sec.\n";
        pnSeri += DiffTmSec(startTm, stopTm);
    }
    double pnPall = 0.0;
    for (int i = 0; i &amp;lt; CHECKNUM; ++i) {
        _ftime_s(&amp;amp;startTm);
        cnt = GetPrimeNumbersParallel(PRIMENUMBERS);
        _ftime_s(&amp;amp;stopTm);
        std::cout &amp;lt;&amp;lt; "素数 パラレル " &amp;lt;&amp;lt; cnt &amp;lt;&amp;lt; "個\t"
            &amp;lt;&amp;lt; DiffTmSec(startTm, stopTm) &amp;lt;&amp;lt; " sec.\n";
        pnPall += DiffTmSec(startTm, stopTm);
    }
    std::cout &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "BubbleSort シリアル平均 "
        &amp;lt;&amp;lt; (bsSeri / (float)CHECKNUM) &amp;lt;&amp;lt; " sec.\n";
    std::cout &amp;lt;&amp;lt; "BubbleSort パラレル平均 "
        &amp;lt;&amp;lt; (bsPall / (float)CHECKNUM) &amp;lt;&amp;lt; " sec.\n";
    std::cout &amp;lt;&amp;lt; "FizzBuzz シリアル平均 "
        &amp;lt;&amp;lt; (fbSeri / (float)CHECKNUM) &amp;lt;&amp;lt; " sec.\n";
    std::cout &amp;lt;&amp;lt; "FizzBuzz パラレル平均 "
        &amp;lt;&amp;lt; (fbPall / (float)CHECKNUM) &amp;lt;&amp;lt; " sec.\n";
    std::cout &amp;lt;&amp;lt; "素数 シリアル平均 "
        &amp;lt;&amp;lt; (pnSeri / (float)CHECKNUM) &amp;lt;&amp;lt; " sec.\n";
    std::cout &amp;lt;&amp;lt; "素数 パラレル平均 "
        &amp;lt;&amp;lt; (pnPall / (float)CHECKNUM) &amp;lt;&amp;lt; " sec.\n";
    std::cout &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "BubbleSort 処理効率 " &amp;lt;&amp;lt; (bsSeri / bsPall) &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "FizzBuzz 処理効率 " &amp;lt;&amp;lt; (fbSeri / fbPall) &amp;lt;&amp;lt; "\n";
    std::cout &amp;lt;&amp;lt; "素数 処理効率 " &amp;lt;&amp;lt; (pnSeri / pnPall) &amp;lt;&amp;lt; "\n";
    /**/
    return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="src_frame"&gt;
&lt;div class="caption"&gt;実行結果（一例）&lt;/div&gt;
&lt;pre class="src"&gt;
素数の数を求める範囲    500000
FizzBuzz を求める範囲   30000000
Bubble Sort の要素数    30000
繰り返し回数    5
BubbleSort シリアル     1.326 sec.
BubbleSort シリアル     1.201 sec.
BubbleSort シリアル     1.497 sec.
BubbleSort シリアル     1.28 sec.
BubbleSort シリアル     1.216 sec.
BubbleSort パラレル     31.934 sec.
BubbleSort パラレル     33.521 sec.
BubbleSort パラレル     34.381 sec.
BubbleSort パラレル     33.757 sec.
BubbleSort パラレル     33.679 sec.
FizzBuzz シリアル       5.556 sec.
FizzBuzz シリアル       5.291 sec.
FizzBuzz シリアル       5.322 sec.
FizzBuzz シリアル       5.337 sec.
FizzBuzz シリアル       5.291 sec.
FizzBuzz パラレル       3.106 sec.
FizzBuzz パラレル       3.09 sec.
FizzBuzz パラレル       3.106 sec.
FizzBuzz パラレル       3.09 sec.
FizzBuzz パラレル       3.121 sec.
素数 シリアル 41538個   52.922 sec.
素数 シリアル 41538個   52.735 sec.
素数 シリアル 41538個   52.804 sec.
素数 シリアル 41538個   52.737 sec.
素数 シリアル 41538個   52.939 sec.
素数 パラレル 41538個   39.115 sec.
素数 パラレル 41538個   40.582 sec.
素数 パラレル 41538個   40.519 sec.
素数 パラレル 41538個   39.583 sec.
素数 パラレル 41538個   40.921 sec.
BubbleSort シリアル平均 1.304 sec.
BubbleSort パラレル平均 33.4544 sec.
FizzBuzz シリアル平均 5.3594 sec.
FizzBuzz パラレル平均 3.1026 sec.
素数 シリアル平均 52.8274 sec.
素数 パラレル平均 40.144 sec.
BubbleSort 処理効率 0.0389784
FizzBuzz 処理効率 1.72739
素数 処理効率 1.31595
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="p5"&gt;
&lt;h2&gt;検証&lt;/h2&gt;
&lt;p&gt;　さあ、結果を検証しましょう。それぞれのアルゴリズムの主要な要素数を変更して、実行しました。結果の一例を、表形式で表します。&lt;/p&gt;
&lt;div class="tbl_frame"&gt;
&lt;div class="cap"&gt;Bubble Sortの計測結果&lt;/div&gt;
&lt;table class="tbl" width="500" style="text-decoration:line-through;"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class="th"&gt;要素数&lt;/td&gt;
            &lt;td class="th" colspan="2"&gt;10000&lt;/td&gt;
            &lt;td class="th" colspan="2"&gt;20000&lt;/td&gt;
            &lt;td class="th" colspan="2"&gt;30000&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&amp;nbsp;&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;1回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;0.4060&lt;/td&gt;
            &lt;td&gt;6.1150&lt;/td&gt;
            &lt;td&gt;1.6380&lt;/td&gt;
            &lt;td&gt;24.0090&lt;/td&gt;
            &lt;td&gt;3.6510&lt;/td&gt;
            &lt;td&gt;54.057&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;2回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;0.4210&lt;/td&gt;
            &lt;td&gt;6.2410&lt;/td&gt;
            &lt;td&gt;1.6530&lt;/td&gt;
            &lt;td&gt;25.3200&lt;/td&gt;
            &lt;td&gt;3.8530&lt;/td&gt;
            &lt;td&gt;56.287&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;3回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;0.4060&lt;/td&gt;
            &lt;td&gt;6.2560&lt;/td&gt;
            &lt;td&gt;1.7010&lt;/td&gt;
            &lt;td&gt;25.3660&lt;/td&gt;
            &lt;td&gt;3.9000&lt;/td&gt;
            &lt;td&gt;56.474&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;4回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;0.4050&lt;/td&gt;
            &lt;td&gt;6.2250&lt;/td&gt;
            &lt;td&gt;1.6380&lt;/td&gt;
            &lt;td&gt;25.1940&lt;/td&gt;
            &lt;td&gt;3.6820&lt;/td&gt;
            &lt;td&gt;56.443&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;5回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;0.4210&lt;/td&gt;
            &lt;td&gt;6.3180&lt;/td&gt;
            &lt;td&gt;1.6690&lt;/td&gt;
            &lt;td&gt;25.3040&lt;/td&gt;
            &lt;td&gt;3.8070&lt;/td&gt;
            &lt;td&gt;56.459&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&lt;strong&gt;平均&lt;/strong&gt;&lt;/td&gt;
            &lt;td class="row_header"&gt;0.4118&lt;/td&gt;
            &lt;td class="row_header"&gt;6.2310&lt;/td&gt;
            &lt;td class="row_header"&gt;1.6598&lt;/td&gt;
            &lt;td class="row_header"&gt;25.0386&lt;/td&gt;
            &lt;td class="row_header"&gt;3.7786&lt;/td&gt;
            &lt;td class="row_header"&gt;55.944&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&lt;strong&gt;処理効率&lt;/strong&gt;&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;0.06608891&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;0.066289649&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;0.067542543&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="tbl_frame"&gt;
&lt;div class="cap"&gt;FizzBuzzの計測結果&lt;/div&gt;
&lt;table class="tbl" width="500" style="text-decoration:line-through;"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class="th" width="80"&gt;要素数&lt;/td&gt;
            &lt;td class="th" width="140" colspan="2"&gt;10000000&lt;/td&gt;
            &lt;td class="th" width="140" colspan="2"&gt;20000000&lt;/td&gt;
            &lt;td class="th" width="140" colspan="2"&gt;30000000&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&amp;nbsp;&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;1回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;3.4790&lt;/td&gt;
            &lt;td&gt;1.9350&lt;/td&gt;
            &lt;td&gt;7.7220&lt;/td&gt;
            &lt;td&gt;3.8070&lt;/td&gt;
            &lt;td&gt;11.384&lt;/td&gt;
            &lt;td&gt;5.9430&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;2回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;3.4330&lt;/td&gt;
            &lt;td&gt;1.8870&lt;/td&gt;
            &lt;td&gt;7.9250&lt;/td&gt;
            &lt;td&gt;3.8370&lt;/td&gt;
            &lt;td&gt;10.920&lt;/td&gt;
            &lt;td&gt;5.8820&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;3回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;3.4320&lt;/td&gt;
            &lt;td&gt;1.8570&lt;/td&gt;
            &lt;td&gt;7.3910&lt;/td&gt;
            &lt;td&gt;3.8380&lt;/td&gt;
            &lt;td&gt;10.921&lt;/td&gt;
            &lt;td&gt;5.8190&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;4回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;3.4320&lt;/td&gt;
            &lt;td&gt;1.9190&lt;/td&gt;
            &lt;td&gt;7.3950&lt;/td&gt;
            &lt;td&gt;3.8220&lt;/td&gt;
            &lt;td&gt;10.874&lt;/td&gt;
            &lt;td&gt;5.8190&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;5回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;3.4480&lt;/td&gt;
            &lt;td&gt;1.9030&lt;/td&gt;
            &lt;td&gt;7.5290&lt;/td&gt;
            &lt;td&gt;3.8220&lt;/td&gt;
            &lt;td&gt;10.921&lt;/td&gt;
            &lt;td&gt;5.8040&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&lt;strong&gt;平均&lt;/strong&gt;&lt;/td&gt;
            &lt;td class="row_header"&gt;3.4448&lt;/td&gt;
            &lt;td class="row_header"&gt;1.9002&lt;/td&gt;
            &lt;td class="row_header"&gt;7.5924&lt;/td&gt;
            &lt;td class="row_header"&gt;3.8252&lt;/td&gt;
            &lt;td class="row_header"&gt;11.004&lt;/td&gt;
            &lt;td class="row_header"&gt;5.8534&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&lt;strong&gt;処理効率&lt;/strong&gt;&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;1.812861804&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;1.984837394&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;1.87993303&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="tbl_frame"&gt;
&lt;div class="cap"&gt;素数（の数）を求めるの計算結果&lt;/div&gt;
&lt;table class="tbl" width="500" style="text-decoration:line-through;"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class="th" width="80"&gt;要素数&lt;/td&gt;
            &lt;td class="th" width="140" colspan="2"&gt;100000&lt;/td&gt;
            &lt;td class="th" width="140" colspan="2"&gt;300000&lt;/td&gt;
            &lt;td class="th" width="140" colspan="2"&gt;500000&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&amp;nbsp;&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
            &lt;td class="row_header"&gt;シリアル&lt;/td&gt;
            &lt;td class="row_header"&gt;パラレル&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;1回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;2.6990&lt;/td&gt;
            &lt;td&gt;2.3400&lt;/td&gt;
            &lt;td&gt;22.7450&lt;/td&gt;
            &lt;td&gt;15.5390&lt;/td&gt;
            &lt;td&gt;52.4810&lt;/td&gt;
            &lt;td&gt;38.5330&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;2回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;2.6990&lt;/td&gt;
            &lt;td&gt;2.3240&lt;/td&gt;
            &lt;td&gt;21.2480&lt;/td&gt;
            &lt;td&gt;15.4930&lt;/td&gt;
            &lt;td&gt;52.4970&lt;/td&gt;
            &lt;td&gt;38.7670&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;3回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;2.7140&lt;/td&gt;
            &lt;td&gt;2.3250&lt;/td&gt;
            &lt;td&gt;20.9510&lt;/td&gt;
            &lt;td&gt;15.4150&lt;/td&gt;
            &lt;td&gt;52.6060&lt;/td&gt;
            &lt;td&gt;39.0010&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;4回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;2.7150&lt;/td&gt;
            &lt;td&gt;2.3870&lt;/td&gt;
            &lt;td&gt;21.0290&lt;/td&gt;
            &lt;td&gt;15.4920&lt;/td&gt;
            &lt;td&gt;52.4500&lt;/td&gt;
            &lt;td&gt;38.9240&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;5回目&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;2.6980&lt;/td&gt;
            &lt;td&gt;2.4960&lt;/td&gt;
            &lt;td&gt;20.9980&lt;/td&gt;
            &lt;td&gt;15.8210&lt;/td&gt;
            &lt;td&gt;52.5430&lt;/td&gt;
            &lt;td&gt;38.8140&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&lt;strong&gt;平均&lt;/strong&gt;&lt;/td&gt;
            &lt;td class="row_header"&gt;2.7050&lt;/td&gt;
            &lt;td class="row_header"&gt;2.3744&lt;/td&gt;
            &lt;td class="row_header"&gt;21.3942&lt;/td&gt;
            &lt;td class="row_header"&gt;15.5520&lt;/td&gt;
            &lt;td class="row_header"&gt;52.5154&lt;/td&gt;
            &lt;td class="row_header"&gt;38.8078&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class="row_header"&gt;&lt;strong&gt;処理効率&lt;/strong&gt;&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;1.139235175&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;1.375655864&lt;/td&gt;
            &lt;td class="row_header" colspan="2"&gt;1.353217652&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;　バブルソートについては、並列化をする方が遅い結果となりました。これは、並列化して実行する処理のほとんどを&lt;span style="color:red;"&gt;順次実行としたため、順番を守るために待ち合わせが発生しているためと考えられます。なお、この例ではループを単純に並列化しようとしたため、この様な結果になっています。パイプライン並列化する等、並列化の方法を変更すると、並列化の効率が良くなります。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;　素数（の数）を求めると、FizzBuzzで、並列化による効果が異なります。FizzBuzzでは1.8倍の効果が出ていますが、素数（の数）を求めるでは、1.3倍にとどまっています。並列化で実行されるループの中の処理が、ループの後ろほど数が多いことが原因です。&lt;/p&gt;
&lt;p&gt;　素数（の数）を求める処理では、「2以下の素数の数」「3以下の素数の数」&amp;hellip;「100以下の素数の数」と数が進むにつれて、だんだんと調べる数が多くなります。Open MPの&lt;code&gt;for&lt;/code&gt;ディレクティブでは、1つのスレッドが実行するループの回数を制御します。&lt;span style="color:red;"&gt;例えば、全体で千回のループであれば、(1000/論理CPU数)回のループを(論理CPU数)回繰り返すような動作をします。この(論理CPU数)回の繰り返しを、並列に処理するわけです。&lt;/span&gt;今、50万以下の素数を求めるわけですが、論理CPU数が2の環境では、「25万未満」と、「25万以上50万以下」の2つに分けて実行します。すると、「25万未満」を担当するスレッドは、「25万以上50万以下」を担当するスレッドよりも、処理の時間が圧倒的に短くなります。すなわち、いずれかのスレッドの負荷だけが上がり、負荷の平準化がされないために、効率が上がらないのです。これを、「100ずつ」に区切って5,000回のタスクに分けると、1つめのタスクと5,000個目のタスクでは処理にかかる時間が大きく異なりますが、1つめのタスクと2つめのタスクでは、わずかな差しかありません。2つのスレッドに負荷を平準化して掛けることにより、処理効率を上げることができます。今回のコードでは、こういう処理をしていないため、1.3倍の効率しか出ていません。&lt;span style="color:red;"&gt;schedule句によって、「ループの回数を小さくする（&lt;code&gt;schedule(static)&lt;/code&gt;）」か、「ループの後ろの方ほどループ回数を小さくする（&lt;code&gt;schedule(guided)&lt;/code&gt;）」ことで、実行効率を上げることが出来ます。&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;　この結果から、何でもかんでも並列化すれば、等しく速くなるわけではない、ということが分かります。並列化に向いているアルゴリズム、向いていないアルゴリズムがあります。また、並列化にむいているアルゴリズムであっても、十分に検討しなければ思わぬバグを作り込んだり&lt;span style="color:red;"&gt;、思ったほど効率が上がらない&lt;/span&gt;ことになります。事前にしっかりと調査し、コードの設計をすることが必要です。&lt;/p&gt;
&lt;h3&gt;並列化する前に&lt;/h3&gt;
&lt;ol&gt;
    &lt;li&gt;パフォーマンスを計測し、高速化しなければならないか、検討する
    &lt;ul&gt;
        &lt;li&gt;10ミリ秒で終わる処理を5ミリ秒にしたところで、どれほどの意味があるでしょうか。1分かかるところを40秒で処理できるようにするのは、意味があるでしょう。すなわち、「何倍」という倍率よりも、体感できる時間を短くする方が大事です。&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;より効率化された書き方がないか、調査する
    &lt;ul&gt;
        &lt;li&gt;例示した「素数か判定する」ルーチンは、判定に使う数は判定したい数の平方根を超えない整数まででかまいません（&lt;code&gt;IsPrimeNumberFast&lt;/code&gt;関数を参照）。&lt;span style="color:red;"&gt;並列化ではたかだか論理CPU数倍にしかなりませんが、&lt;code&gt;IsPrimeNumberFast&lt;/code&gt;関数を使うと、実行効率は100倍以上になります。&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;ここでは、「並列化に向かないアルゴリズム」の説明として、&lt;span style="color:red;"&gt;複数のスレッドが同時に同じ領域を変更する例として、&lt;/span&gt;バブルソートを選びました。ソートをするなら、クイックソートやマージソートなど、より効率的なアルゴリズムがあります。&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;処理を、より単純化する&lt;/li&gt;
    &lt;li&gt;並列化できる箇所を明確にする
    &lt;ul&gt;
        &lt;li&gt;本文では、いくつかの並列化できない箇所を、予め廃止するか並列化しない箇所へ退避させています。コンソール出力をやめる、メモリの確保を前もって行うなどです。&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;並列に動作すると不具合を引き起こす箇所がないか、検証する
    &lt;ul&gt;
        &lt;li&gt;処理順序が一定であることに依存しないか、検証します。FizzBuzz問題を、ループ内でコンソールに出力すると、処理順序が一定ではないことが問題になります。そのため、決められた位置へ格納するというアルゴリズムに変更しています。&lt;/li&gt;
        &lt;li&gt;複数のスレッドで、同じ領域を書き換えることがないか、検証します（&lt;span style="color:red;"&gt;「生産者と消費者問題」で検索して下さい&lt;/span&gt;）。&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;不具合を起こす箇所を一か所にまとめ、クリティカルブロックとする
    &lt;ul&gt;
        &lt;li&gt;デッドロックしないように、慎重に設計します（&lt;span style="color:red;"&gt;「哲学者の食事問題」で検索して下さい&lt;/span&gt;）。&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;クリティカルブロックの処理時間と、並列化している箇所の処理時間を比較する&lt;/li&gt;
    &lt;li&gt;クリティカルブロックの処理時間が長い場合、並列化をあきらめる&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;謝辞&lt;/h2&gt;
&lt;p&gt;　本記事は、一旦ブログにて公開し、コミュニティの皆さまよりご意見をいただいて、より読みやすいように修正しました。ご協力くださった方々に、この場を借りてお礼申し上げます。&lt;/p&gt;
&lt;/div&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/185818.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>[MSDN]MSDN サブスクライバー必見！</title><link>http://blogs.wankuma.com/jitta/archive/2009/12/16/183891.aspx</link><pubDate>Wed, 16 Dec 2009 22:39:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2009/12/16/183891.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/183891.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2009/12/16/183891.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/183891.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/183891.aspx</trackback:ping><description>&lt;P class=p&gt;今頃気がついた（というか、砂金さんのブログを見た）が、MSDN サブスクリプションに、「特別な特典」が追加されています→&lt;A class=outerLink title=⇒microsoft.com href="http://msdn.microsoft.com/ja-jp/subscriptions/dd347471(en-us).aspx"&gt;このページ&lt;/A&gt;（英語）&lt;/P&gt;
&lt;P class=p&gt;Telerik 社のコンポーネントは、実は ASP.NET 分野の MVP だけに、ASP.NET コンポーネントが無償提供されたことがあります。その時に申し込んで使ってみたのですが、デモを見るだけでも楽しいですよ（この特典は、WinForm 用です）。&lt;/P&gt;
&lt;P class=p&gt;英語で書いてあるし、提供されるコンポーネントも英語だけれど、パワフルなコンポーネントです。使ってみましょう！&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/183891.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>1から10まで足す、ですって？</title><link>http://blogs.wankuma.com/jitta/archive/2009/10/01/181760.aspx</link><pubDate>Thu, 01 Oct 2009 22:41:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2009/10/01/181760.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/181760.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2009/10/01/181760.aspx#Feedback</comments><slash:comments>23</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/181760.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/181760.aspx</trackback:ping><description>&lt;p class="p"&gt;プチ祭り？「&lt;A href="http://blogs.wankuma.com/rti/archive/2009/09/29/181710.aspx"&gt;気がつくと&lt;/a&gt;」とか、「&lt;A href="http://blogs.wankuma.com/andochin/archive/2009/09/30/181717.aspx"&gt;[C++] １から１０まで足す&lt;/a&gt;」とか、「&lt;A href="http://blogs.wankuma.com/episteme/archive/2009/09/30/181731.aspx"&gt;1+2+&amp;#8230;+10&lt;/a&gt;」とか、「&lt;A href="http://blogs.wankuma.com/hirase/archive/2009/09/30/181733.aspx"&gt;[C] 1から10までの総和をマクロでエレファントに解く。&lt;/a&gt;」とか。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;「55と出力する」に決まってるじゃないですか。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
10 REM This code is written for N80-BASIC
20 PRINT 55
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;大元のネタは、おそらく、&lt;a href="http://el.jibun.atmarkit.co.jp/g1sys/2009/09/post-38ec.html" title="⇒atmarkit.co.jp" class="outerLink"&gt;「転職活動する暇があったらブログを書け」について&lt;/a&gt;（ベンチャー社長で技術者で）だと思います。私の答えは、&lt;q&gt;一般社会ではそれではダメで、意図がまったく読み取れてないからゼロです。&lt;/q&gt;だ、そうです。&lt;/p&gt;
&lt;p class="p"&gt;うむ、そうですか。私は、意図を、読みません。だって、読み間違えていたら、手戻り作業が大変じゃないですか。だから、意図は尋ね、確認します。・・・いや、ごめんなさい。これからは確認します。今、意図を読み違えて大変なことになっているのよ～～(T^T)&lt;/p&gt;
&lt;p class="p"&gt;私が上記のようなコードを書いた意図は、わざわざ「written for N80-BASIC」と、今回は remark を振ったところにあります。N80-BASIC は、インタープリター言語です。逐次翻訳です。FOR 文を書いたら、命令をコンパイルしながら実行するので、遅いのです。先に計算できるものはしておく。インタープリター言語を使っていた頃の、ひとつの知識です。&lt;/p&gt;
&lt;p class="p"&gt;もちろん、C/C++ で、次のように書くのもありです。これもコンパイル時に最適化で計算されてしまいます。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
#include "stdafx.h"
#include &amp;lt;iostream&amp;gt;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    cout &amp;lt;&amp;lt; 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 &amp;lt;&amp;lt; endl;
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;
&lt;p class="p"&gt;ところで、ここのコメントに、「10億だったら&amp;#8230;」とありますが。&lt;/p&gt;
&lt;p class="p"&gt;まず、10億だったら、答えは何か。&lt;br&gt;
10だと、55&lt;br&gt;
100だと、5050&lt;br&gt;
1000だと、500500、です。法則が見えましたね。&lt;br&gt;
10億は1000000000、0が9個あるので、5の後に0を8個入れた、500000000500000000&amp;#8230;50京5億です。&lt;/p&gt;
&lt;p class="p"&gt;これがコンピューターに計算できるか？微妙です。なぜなら、コンピューターが扱える数の範囲には、限りがあるからです。&lt;/p&gt;
&lt;p class="p"&gt;演算に用いる型のビット数が32ビットの場合、約21億（符号無しで約42億）が最大となります。このため、32ビットの整数型では、計算途中にオーバーフローが発生します。64ビットだと、約922京（符号無しだと約1844京）です。SQL Server や Oracle ではもっと大きな数字を扱えます。SQL Server 2005以降と Oracle では38桁扱えます。えっと。。。京、垓、杼（正しくはノ木偏）、穣、溝、澗の、澗（カン）だそうです。&lt;/p&gt;
&lt;p class="p"&gt;じゃぁ、64ビットだと、いくつまで計算できるでしょうか。10億で50京です。100億だと5千京です。ああ、超えた。。。&lt;/p&gt;
&lt;p class="p"&gt;反対にしよう。総和が922京になる数字を求めよう。・・・4294967295。これの答えが9223372034707292160。約922京なので、求められるはずです。&lt;/p&gt;
&lt;p class="p"&gt;ところが、生島さんが期待する「(n + 1) &amp;#215; n &amp;#247; 2」の計算式では、答えが求められないのです。&lt;/p&gt;
&lt;p class="p"&gt;なぜでしょう？&lt;/p&gt;
&lt;p class="p"&gt;「(n + 1) &amp;#215; n」で、約1844京となり、桁あふれを起こすからです。&lt;span class="comment"&gt;922京を2倍して平方根を取ると、42億になります。が、それを先に書くと1844京という値が先に出てしまい、オーバーフローがチョンばれです。その為、上ではいきなり42億という数字を出しています。&lt;/span&gt;&lt;/p&gt;
&lt;pre class="code"&gt;検証&lt;code&gt;
#include "stdafx.h"
#include &amp;lt;iostream&amp;gt;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    __int64 max = 4294967295;
    __int64 sum = 0;
    for (__int64 i = 1; i &amp;lt;= max; ++i) {
        sum += i;
    }
    cout &amp;lt;&amp;lt; sum &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; (max + 1) * max / 2 &amp;lt;&amp;lt; endl;
    return 0;
}
&lt;/code&gt;
結果
C:\Projects\TestSolution\Debug&gt;totalSum.exe
9223372034707292160
-2147483648
&lt;/pre&gt;
&lt;p class="p"&gt;これを防ぐためには、「(n + 1) &amp;#215; (n &amp;#247; 2)」とするのが、ひとつの方法です。しかし、n が奇数の場合、正しい結果が得られません（9223372032559808512になる）。整数と整数の除算は整数になり、0.5が捨てられるからです。n が奇数の場合は、「((n + 1) &amp;#247; 2) &amp;#215; n」とします。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
#include "stdafx.h"
#include &amp;lt;iostream&amp;gt;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    __int64 max = 4294967295;
    __int64 sum = 0;
    for (__int64 i = 1; i &amp;lt;= max; ++i) {
        sum += i;
    }
    cout &amp;lt;&amp;lt; sum &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; (max + 1) * max / 2 &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; ((max % 2 == 1) ? ((max + 1) / 2) * max
                                  : (max + 1) * (max / 2))
        &amp;lt;&amp;lt; endl;
    return 0;
}
&lt;/code&gt;
結果
C:\Projects\TestSolution\Debug&gt;totalSum.exe
9223372034707292160
-2147483648
9223372034707292160
&lt;/pre&gt;
&lt;br&gt;
&lt;p class="p"&gt;今回は固定の数字を求めましたが、ユーザーによる手入力の場合は、上限を超えるような数字ではないことを確認しておく必要があるかもしれません。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/181760.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>並列ナントカ</title><link>http://blogs.wankuma.com/jitta/archive/2009/09/18/181436.aspx</link><pubDate>Fri, 18 Sep 2009 23:35:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2009/09/18/181436.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/181436.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2009/09/18/181436.aspx#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/181436.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/181436.aspx</trackback:ping><description>&lt;p class="p"&gt;&lt;a href="http://codezine.jp/article/detail/3946" title="⇒codezine.jp" class="outerLink"&gt;インテル Parallel Studioを使って並列化プログラミングを試してみた&lt;/a&gt;（codeZine）より。&lt;/p&gt;
&lt;p class="p"&gt;ん。。。また、違和感のある記事。。。&lt;/p&gt;
&lt;blockquote cite="http://codezine.jp/article/trackback/3946"&gt;
&lt;p&gt;　しかしここ数年の間に大きな変化がありました。それはCPUのマルチコア化です。2006年にPentium 4シングルコアの製造が中止され、Intel Core 2が発売され始めた時、筆者は非常に衝撃を受けました。なぜならば、それは従来の開発技法が通用しないことを意味するからです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;記事を通して、従来のどのような開発技法が通用しなくなるのか、説明がない。まぁ、それは、次の説明から、推し量ることは出来る。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;もう単一CPUの時代は終わり、CPUのマルチコア化が進んで行きますので、開発者もそれに伴って並列プログラミングをする必要性が生じました。&lt;/p&gt;
&lt;p&gt;　今までシングルコアのCPUが主流だったからといって、並列プログラミングがまったくなかったわけではありません。今までもマルチスレッドプログラミングを行っていた人も多いと思います。この手法でもコア数が2ならば十分に対応可能でしょう。&lt;/p&gt;
&lt;p&gt;　しかし、コア数が4・8・16・32・64・&amp;#8230;&amp;#8230;と増えるにつれてこの方法では対処できなくなります。また、コア数を固定したプログラミング方法では、エンドユーザーがCPUを買い換えた時パフォーマンスがアップしません。エンドユーザーは新しいCPUを買えばシステムの性能がよくなると考えていますので、これではシステム不備だと看做されてしまうでしょう。今後コア数が増加することは目に見えていますので、新しい技術が必要なのは明白です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;なんだか違和感。&lt;/p&gt;
&lt;p class="p"&gt;マルチ コア化が進んできたから、並列プログラミングをする必要が生じるのだろうか。そんなことはない。シングル コアであっても、並列プログラミングをする必要はあったし、そのメリットもあった。業務システムを作る上で、一番スピードを出しにくいところは、ユーザーが入力を行うところです。人が操作するスピードは、機械がどんなに速くなろうと、そうそう変わりません。その為、ユーザーが入力している間に何か処理をする、ということは、スピードアップについてとても有効です。はい、ここに並列プログラミングをする理由があります。&lt;/p&gt;
&lt;p class="p"&gt;同じように、ネットワーク アクセス、ディスク アクセスなどの I/O が絡むところは、他の処理を並列に行う事でスピードを上げることが出来ます。CPU のスピードに比べて、メモリやディスク、人が処理をするスピードは、十分に遅いからです。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;次、コア数。コア数が3以上と3未満とで、マルチ スレッド プログラミングに違いがあるのか？無いと思います。英語のウィキペディアから引用します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="quoteSource"&gt;&lt;a href="http://en.wikipedia.org/wiki/Sun_Microsystems#SPARC-based_systems" title="⇒wikipedia.org" class="outerLink"&gt;Sun Microsystems&lt;/a&gt;（Wikipedia）より：&lt;/p&gt;
&lt;p&gt;In the early 1990s the company began to extend its product line to include large-scale symmetric multiprocessing servers, starting with the four-processor SPARCserver 600MP. This was followed by the 8-processor SPARCserver 1000 and 20-processor SPARCcenter 2000, which were based on work done in conjunction with Xerox PARC. In the late 1990s this transformation was accelerated by the acquisition of Cray Business Systems Division from Silicon Graphics.[35] Their 32-bit, 64-processor Cray Superserver 6400, related to the SPARCcenter, led to the 64-bit Sun Enterprise 10000 high-end server (otherwise known as Starfire). More recently, Sun has also ventured into the blade server (high density rack-mounted systems) market.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;Windows NT 4.0 の頃、マザーボードに2つの CPU を付けることが出来るものがありました。それと、ひとつの CPU でコアがふたつある状態。OS にとっては違うかもしれませんが、OS の上で動くアプリケーションにとって、何が違うのでしょう。&lt;/p&gt;
&lt;p class="p"&gt;インテルの CPU は2つしか積むことが出来ませんでしたが、サン マイクロシステムズの CPU は、1990年代の初めでも4つのプロセッサーを同時に搭載可能でした。その後、8プロセッサー、20プロセッサーに対応したハードウェアが発表されています。私も、1997年頃に4プロセッサーの製品を使用したことがあります。&lt;span class="comment"&gt;（8プロセッサーの予定が、予算の都合で4に減った。その後、現地での最終試験中に「パフォーマンスが目標に達しない」事が判明。急遽&amp;#8220;もう1台&amp;#8221;追加することに。ハードウェアを納める筐体に収まりきらないというおまけ付き。）&lt;/span&gt;それまでの開発手法と、その時の開発手法、今の開発手法。特に意識して変えてはいません。「通用しなくなる」というのは、納得できない。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/181436.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>「オブジェクト指向」ってなんじゃらほい？（その3）</title><link>http://blogs.wankuma.com/jitta/archive/2009/01/20/166558.aspx</link><pubDate>Tue, 20 Jan 2009 23:30:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2009/01/20/166558.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/166558.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2009/01/20/166558.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/166558.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/166558.aspx</trackback:ping><description>&lt;p class="p"&gt;前回は、オブジェクト志向プログラミングだと変更がしやすいと、書きました。本当でしょうか？検証してみましょう。&lt;/p&gt;
&lt;p class="p"&gt;では、元のお題「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所に移動する。」を変更します。&lt;br&gt;
「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所、または FTP サーバー上の任意の場所に移動する。」&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;移動先に、FTP サーバーを追加しました。さて、プロセス志向ナントカ、オブジェクト志向ナントカは、それぞれどのように変わるでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;プロセス志向設計では、処理の途中で「移動先が FTP サーバーなら、&amp;#8230;」と、分岐が必要です。しかし、オブジェクト志向設計は、「ファイルの属性「場所」を、新しい場所に設定する。」のまま変わりません。その「新しい場所」がローカル ディスクなのか、FTP サーバーなのかは、この設計では揺らがないのです。&lt;/p&gt;
&lt;p class="p"&gt;ただし、プログラミングのレベルにまで落とせば、どこかで「ファイルを移動させる」という処理をしなければなりません。プロセス志向プログラミングでは、プロセス（手続き）の中に「移動させる」を書きました。オブジェクト志向プログラミングでは、いくつかの方法があります。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;ひとつは、ファイル オブジェクトのメソッドの中に、プロセス志向プログラミングと同じように書き込む方法です。「オブジェクト志向」といっても、どこかでプロセスにも目を向けなければなりません。そこに実装するのがひとつ。&lt;/p&gt;
&lt;p class="p"&gt;しかし、そんなことをしていては、本当に「変更が容易」とは言い難いです。新しい「移動先」を追加するごとに、ファイル クラスを修正しなければなりません。それではプロセス志向プログラミングとかわりありません。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;そこで、やはりオブジェクトに志向することにします。&lt;/p&gt;
&lt;p class="p"&gt;「ファイルを移動する」ということは、「どこかにあるファイルを、どこかへ持って行く」ということです。「持って行く」です。誰が？はい、ここに「オブジェクト」が潜んでいました。「ファイルの移動を行うオブジェクト」です。&lt;/p&gt;
&lt;p class="p"&gt;この、「ファイルの移動を行うオブジェクト」が、「ローカル ディスクからローカル ディスクへ移動させる」ことや、「ローカル ディスクから FTP サーバー上のディレクトリへ移動させる」ことが出来ればいいのです。つまり、「移動」というメソッドに、「ファイル」オブジェクトと「新しい場所」をパラメータとして引き渡せるようにします。&lt;/p&gt;
&lt;p class="p"&gt;とはいえ、これでもやはり、新しい場所について新しい概念が追加されると、「ファイルの移動を行うオブジェクト」の中を変更しなければなりません。先ほどと変わりがないだけでなく、クラスが増えた分、管理が面倒になるだけです。&lt;/p&gt;
&lt;p class="p"&gt;ここで、オブジェクト志向ナントカにあって、プロセス志向ナントカにはないものを使います。汎化と特化です。&lt;/p&gt;
&lt;p class="p"&gt;今、「ファイルの移動を行うオブジェクト」に対して、「ローカル ディスクからローカル ディスクへ移動させる」「ローカル ディスクから FTP サーバー上のディレクトリへ移動させる」を考えました。「ファイルを移動させる」という動作について、移動先を「ローカル ディスク」「FTP サーバー上のディレクトリ」という場合に分けました。これが特化です。「移動させる」という汎用的な機能を、移動先を特定し、絞り込んだわけです。反対に、「ローカル ディスク上の」という特定された機能から、「いや、FTP とか、HTTP サーバーとかもあるかもしれない」と考え、場所を特定しない、汎用的な「移動する」へと考えを広げることが汎化です。もっとも、ここでは「機能」ですが、オブジェクトに志向するのですから、機能だけでなく、情報も対象になります。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;もうひとつ、オブジェクトに指向した例です。先ほどは、「オブジェクトを移動させるもの」を作りました。しかし、ファイルというオブジェクトが「移動してくる場所」も、オブジェクトです。ですから、「場所オブジェクト」に「指定されたファイルを作る」メソッドと、「指定されたファイルを消す」メソッドを用意することもできます。この方法でも、「場所」は汎化、特化で表されます。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;では、この汎化と特化によって、何がどうなるのでしょう？こんなふうになります。&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;ファイルのインスタンスを作成する。&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p&gt;「ファイルを移動させる」オブジェクト（「場所」オブジェクト）を作成する。&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p&gt;「ファイルを移動させる」オブジェクト（「場所」オブジェクト）によって、ファイルを移動させる。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;これによって、ファイルの場所に関する新しい概念が出来たとき、その概念に特化した「ファイルを移動させるクラス」を作成することになります。クラスが分かれているので、「移動させる」部分については、ファイルの場所が増えることによる変更の影響を受けません。新しい「ファイルを移動させる」オブジェクトが作成できていることを確認すれば、すでにあったクラスについて、変更の影響を受けていないことを確認する必要はありません。&lt;/p&gt;
&lt;p class="p"&gt;しかし、大きな欠点というか、面倒な点があります。前回は「移動させる」ことをファイル クラスにさせていましたが、今回で移動させるクラスに切り出しました。最初に行った分析が十分ではなかったということです。このように、オブジェクト志向開発による変更が容易であるためには、「最初の分析・設計が十分に行えていれば」という条件がつくのです。この条件こそ、オブジェクト志向開発を難しいものにしているのではないかと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/166558.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>個人の成長と、組織の成長</title><link>http://blogs.wankuma.com/jitta/archive/2008/12/16/164048.aspx</link><pubDate>Tue, 16 Dec 2008 23:39:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/12/16/164048.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/164048.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/12/16/164048.aspx#Feedback</comments><slash:comments>35</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/164048.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/164048.aspx</trackback:ping><description>&lt;P class=p&gt;&lt;A href="http://blogs.wankuma.com/jitta/archive/2008/11/21/161892.aspx"&gt;できるヤツから離れていく&lt;/A&gt;より発展。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;多くの場合、たった一人の人だけで仕事をすることはありません。営業に回って仕事を発掘し、折衝して仕様をフィックスし、仕様を元に設計、設計を元にコーディング、仕様、設計を元にテスティング、パッケージして納品してお客様に説明して、そして長いメンテナンスの期間へと移行．．．これを全て一人で回している方って、いらっしゃるのでしょうか。&lt;/P&gt;
&lt;P class=p&gt;つまり、人は、チームで仕事をします。「チームひとり」の時も、それは設計からテスティングあたりまでがひとりなだけで、受注や納品、メンテナンスは、他の人が担当していないでしょうか。&lt;/P&gt;
&lt;P class=p&gt;フリーで仕事をされている方も、ご自身の仕事は、ご自身で探してきていらっしゃるでしょう。しかしそれは、エンド ユーザに当たる人のところへ直接営業に出かけているのでしょうか？&lt;/P&gt;
&lt;P class=p&gt;そういえば、父を経由して転職の話があったのですが、「ハードウェアの設計と製造、それ用のミドルウェアの設計と製造、飛び込み営業が出来る人を探しています」といわれ、即座に断りました。ええ、3人ではなく、ひとりだったので。もちろん、こんなマルチな展開を個人個人がやっても、「チームほんとにひとり」ではないのです。何しろ「会社」という組織なのですから。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;閑話休題。&lt;/P&gt;
&lt;P class=p&gt;個人が成長するとき、その成長は個人が考えているところまで、個人のスピードで右肩上がりに伸ばすことが出来ます。ただし、ここでは角度は考えません。ただ、「成長し続けることが出来る」というところにとどめます。&lt;/P&gt;
&lt;P class=p&gt;しかし、多くの人が、企業で働いていると思います。あるいは、フリー エンジニアであっても、何らかのグループとして、仕事をしているでしょう。その企業、あるいはグループの成長は、どうでしょうか。&lt;/P&gt;
&lt;P class=p&gt;個人の場合は、ただ単一の思考によってのみ、コントロールが出来ました。しかし、グループには、複数の個体があります。したがって、個々の思惑が違えば、成長の方向もばらつきが出ます。方向がばらついているだけならかまいません。グループには、「卒業」と「新入」というイベントがあります。これを考えないわけにはいきません。&lt;/P&gt;
&lt;P class=p&gt;企業の場合、毎年のように「退職者」が発生します。その人たちによる生産性の低下を埋めるために、「就職者」が発生します。退職者よりも就職者のスキルが低い場合、組織としての成長は、一旦下がります。概して、多くの経験による知識を持った退職者に比べて、就職者はスキルが低い場合が多いと言っていいと思います。そこで、新しい人のレベルを如何に上げておくのか。それを考えてみるのも面白いと思います。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;算数があります。算数の基礎は、加算だと思います。しかしその前に、「数」というものが定義されていていなければなりません。「１」の次が「２」と決まっていないと、「１，２，３・・・」のように数えることが出来ません。時と場合によって「１，２，３」だったり、「１，５，２」だったりすると困りますよね、ということです。&lt;/P&gt;
&lt;P class=p&gt;数が定義されます。「九」の次は「十」と決められます。「九十九」の次は「百」と決められます。こう決められることで数えることが出来ます。数えることが出来るので、加算が出来ます。&lt;/P&gt;
&lt;P class=p&gt;さて、ここで「知識の伝達・継承」が必要になってきます。誰かが「同じ数を決まった回数加えることを、乗算とする。記号を&amp;#215;とする。」と決めます。この決めたことが広まり、定着しないと、独りよがりなルールになるだけです。知識の伝達・継承には、教育が大きな役割を果たしています。多くの国で、義務教育という制度が設けられ、その制度の中で、基礎的な知識の伝達が行われています。あるいは、教育によって、基礎学力が上昇すると言い換えることが出来るでしょう。&lt;/P&gt;
&lt;P class=p&gt;日本では、義務教育の期間に基礎的な学力を身につけるのが望ましいとされています。ここで「望ましい」としたのは、日本の義務教育は年齢による教育を受ける義務、教育を受けさせる義務であって、一定のレベル以上になることを義務としていないからです。これはこれで別の話題になるので、ここまで。&lt;/P&gt;
&lt;P class=p&gt;さて、基礎的な学力について、です。転じます。基礎的な開発技術力について、です。基礎的な学力は、一応、義務教育の期間に学ぶことが出来ます。さらに勉強したい人は、高等学校へ。さらに興味を持った分野について見識を広めたい人は、大学へ行きます。では、基礎的な開発技術力は、どこで学ぶのでしょうか。&lt;/P&gt;
&lt;P class=p&gt;会社組織に入ってから学ぶのでしょうか。それであれば、新人が入ってきたとたん、組織としての開発力が下がるのは、仕方のないことです。しかし、それでは困ります。困らないためには、下がってもいいだけの開発力がある間に新人を導入し、余力でもって新人に開発技術力を学んでもらわなければなりません。&lt;/P&gt;
&lt;P class=p&gt;先に、算数を学ぶためには数の概念を身につけていなければならないことを示しました。開発の現場でも同じです。物事の考え方、考えのまとめ方、流れの組み立て方、わからないことを調べる方法など。これらについて、ある程度の基礎が出来ていないと、基礎の上にある応用を、まねることは出来ても理解することは出来ません。理解できないなら、それは「開発技術力がある」ことにはなりません。理解が出来ていないということは、どのような場合に適用できるかについて考えることが出来ないということでもあり、同じ方法が適用できる場面で適用できないということだからです。そして、人によって長短はありますが、基礎を身につけ、応用力にまで発展させるには、ある程度時間がかかります。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;このように、個人が成長するのは、個人が思うままにコントロールし、右肩上がりに上げていけます。しかし、組織の成長は、そのようにはならないことがあります。そして、仕事は組織で行うものです。個人が行うのでなく、組織が行う仕事は、その組織の誰か個人が優れた技術を持っているからといって、そのレベルにまで上げることは出来ません。他の個人もいるからです。組織の成長には、波があります。個人の成長と違い、下がることもあります。このとき、一番後ろの人にあわせろとは言いません。しかし、一番前の人にあわせることも、また難しいと思います。この落としどころは、経営的判断によってなされるでしょう。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/164048.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>できるヤツから離れていく</title><link>http://blogs.wankuma.com/jitta/archive/2008/11/21/161892.aspx</link><pubDate>Fri, 21 Nov 2008 19:31:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/11/21/161892.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/161892.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/11/21/161892.aspx#Feedback</comments><slash:comments>66</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/161892.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/161892.aspx</trackback:ping><description>&lt;P class=p&gt;ネタもと：&lt;A href="http://blogs.wankuma.com/episteme/archive/2008/11/21/161829.aspx"&gt;護送船団方式&lt;/A&gt;→&lt;A href="http://blogs.wankuma.com/ognac/archive/2008/11/21/161815.aspx"&gt;1メソッドは 50行以内&lt;/A&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;誰もができる→ダメダメな奴でもできる→できん子に足並み揃える&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;BR&gt;
&lt;P class=p&gt;いやだ。。。&lt;/P&gt;
&lt;P class=p&gt;できん子は、あるいは「新人」に置き換えてもいいと思います。←これは、知識がたまっていないという意味です。&lt;/P&gt;
&lt;P class=p&gt;彫刻や絵画などの、手を動かす技術者は、何度も同じことを繰り返すことで、より短い時間、より少ない手間で同じものを作り、また、より美しいものを作ることができるようになります。ここに護送船団方式はあり得ません。言うなれば、「快速船方式」でしょうか。できるヤツに合わさなければ、売り物にならないのです。&lt;/P&gt;
&lt;P class=p&gt;しかし、ソフトウェア業界では、中身と外見が一致しないことがあります。どんな汚いコードでも、要望がかなっていれば良しとされます。そのため、護送船団方式が通ります。&lt;/P&gt;
&lt;P class=p&gt;このとき、できる人とできない人の差は、知識です。&lt;/P&gt;
&lt;P class=p&gt;επιστημηさんが書かれるコードは、時々理解できません。それは、私に STL の知識がないからです。Ｒ・田中一郎さんが書かれるコードが、時々理解できません。それは、私にラムダ式の知識がないからです。&lt;/P&gt;
&lt;P class=p&gt;じゃぁ、この3人が一緒に仕事をすることになったとき、どうするでしょう？個人組合であれば、それぞれがそれぞれの力量で行います。しかし、企業では、一番知識のない人、つまり私が理解できるコードを書くことが強要されます。なぜなら、新卒もまた、わからないと思われ、メンテナンスを担当することになってしまった人が理解できるかどうか、わからないからです。&lt;/P&gt;
&lt;P class=p&gt;できる人にとっては、面白くないですよね。第一、向上心が削がれます。できる、できないの差は、ここにこそあるはずです。そこを「評価しない」と言っているにも等しいことです。&lt;/P&gt;
&lt;P class=p&gt;結果。できる人から離れていく(辞めていく)ということになるでしょう。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/161892.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>