{"id":324,"date":"2017-05-14T09:00:32","date_gmt":"2017-05-14T09:00:32","guid":{"rendered":"http:\/\/imalogic.com\/blog\/?p=324"},"modified":"2017-07-19T12:34:28","modified_gmt":"2017-07-19T12:34:28","slug":"benchmarking-c-net-direct3d-11-apis-vs-native-c","status":"publish","type":"post","link":"https:\/\/imalogic.com\/blog\/2017\/05\/14\/benchmarking-c-net-direct3d-11-apis-vs-native-c\/","title":{"rendered":"Benchmarking C#\/.Net Direct3D 11 APIs vs native C++"},"content":{"rendered":"<body><p><\/p><strong>This is a resume from a old post found on internet about benchmarking\u00a0Direct3D 11.<\/strong>\n<p><a href=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/t%C3%A9l%C3%A9chargement.jpg?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"328\" data-permalink=\"https:\/\/imalogic.com\/blog\/2017\/05\/14\/benchmarking-c-net-direct3d-11-apis-vs-native-c\/telechargement-3\/\" data-orig-file=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/t%C3%A9l%C3%A9chargement.jpg?fit=310%2C163&amp;ssl=1\" data-orig-size=\"310,163\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"t\u00e9l\u00e9chargement\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/t%C3%A9l%C3%A9chargement.jpg?fit=310%2C163&amp;ssl=1\" class=\"size-medium wp-image-328 alignleft\" src=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/t%C3%A9l%C3%A9chargement-300x158.jpg?resize=300%2C158&#038;ssl=1\" alt=\"\" width=\"300\" height=\"158\" loading=\"lazy\"><\/a>If you are working with a managed language like C# and you are concerned by performance, you probably know that, even if the Microsoft JIT CLR is quite efficient, It has a significant cost over a pure C++ implementation. If you don\u2019t know much about this cost, you have probably heard about a mean cost for managed languages around 15-20%. If you are really concern by this, and depending on the cases, you know that the reality of a calculation-intensive managed application is more often around x2 or even x3 slower than its C++ counterpart.<\/p>\n<p>In this post, I\u2019m going to present a result of micro-benchmark that measure the cost of calling a native Direct3D 11 API from a C# application, using various API, ranging from <a href=\"http:\/\/code.google.com\/p\/sharpdx\/\">SharpDX<\/a>, SlimDX, WindowsCodecPack.<\/p>\n<h1>The Managed (C#) to Native (C++) interop cost<\/h1>\n<p>When a managed application needs to call a native API, it needs to:<\/p>\n<ul>\n<li>Marshal method\/function arguments from the managed world to the unmanaged world<\/li>\n<li>The CLR has to switch from a managed execution to an unmanaged environment (change exception handling, stacktrace state\u2026etc.)<\/li>\n<li>The native methods is effectively called<\/li>\n<li>Than you have to marshal output arguments and results from unmanaged world to managed one.<\/li>\n<\/ul>\n<p>To perform a native call from a managed language, there is currently 3 solutions:<\/p>\n<ul>\n<li><b>Using the default interop mechanism provided under C# is P\/Invoke<\/b>, which is in charge of performing all the previous steps. But P\/Invoke comes at a huge cost when you have to pass some structures, arrays by values, strings\u2026etc.<\/li>\n<li><b>Using a C++\/CLI <\/b>assembly that will perform a marshaling written by hand to the native C++ methods. This is used by SlimDX, WindowsCodePack and XNA.<\/li>\n<li><b>Using SharpDX technique <\/b>that is generating all the marshaling and interop at compile time, in a structured and consistent way, using some missing CLR bytecode inside C# that is usually only available in C++\/CLI<\/li>\n<\/ul>\n<p>The benchmark was ported under:<\/p>\n<ul>\n<li><b>C++<\/b>, using raw native calls and Direct3D11 API<\/li>\n<li><b>SharpDX<\/b>, using Direct3D11 running under Microsoft .NET CLR 4.0 and with Mono 2.10 (both trying llvm on\/off). SharpDX is the only managed API to be able to run under Mono.<\/li>\n<li><b>SlimDX <\/b>using Direct3D11 running under Microsoft .NET CLR 4.0. SlimDX is \u201cNGENed\u201d meaning that it is compiled to native code when you install it.<\/li>\n<li><b>WindowsCodePack <\/b>1.1 using Direct3D11 running under Microsoft .NET CLR 4.0<\/li>\n<\/ul>\n<h1>Results<\/h1>\n<p>You can see the raw results in the following table. Time is measured for the simple drawing sequence (inside the loop for(i) nbEffects). Lower is better. The ratio on the right indicates how much is slower the tested API compare to the C++ one. For example, SharpDX in x86 mode is running 1,52 slower than its pure C++ counterpart.<\/p>\n<table style=\"height: 289px;\" border=\"0\" width=\"738\" cellspacing=\"0\" cellpadding=\"0\">\n<colgroup>\n<col width=\"239\">\n<col span=\"2\" width=\"74\">\n<col span=\"2\" width=\"77\"><\/colgroup>\n<tbody>\n<tr>\n<td class=\"xl63\" width=\"239\" height=\"20\">Direct3D11 Simple Bench<\/td>\n<td class=\"xl63\" width=\"74\">x86 (ms)<\/td>\n<td class=\"xl63\" width=\"74\">x64 (ms)<\/td>\n<td class=\"xl63\" width=\"77\">x86-ratio<\/td>\n<td class=\"xl63\" width=\"77\">x64-ratio<\/td>\n<\/tr>\n<tr>\n<td height=\"20\"><span style=\"color: #99cc00;\">Native C++ (MSVC VS2010)<\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #99cc00;\">0.000386<\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #99cc00;\">0.000262<\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #99cc00;\">x1.00<\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #99cc00;\">x1.00<\/span><\/td>\n<\/tr>\n<tr>\n<td height=\"20\"><span style=\"color: #339966;\">Managed SharpDX (1.3 MS .Net CLR)<\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #339966;\">0.000585<\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #339966;\">0.000607<\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #339966;\">x1.52<\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #339966;\">x2.32<\/span><\/td>\n<\/tr>\n<tr>\n<td height=\"20\"><span style=\"color: #ff6600;\">Managed SlimDX (June 2010 \u2013 Ngen)<\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #ff6600;\">0.000945<\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #ff6600;\">0.000886<\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #ff6600;\">x2.45<\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #ff6600;\">x3.38<\/span><\/td>\n<\/tr>\n<tr>\n<td height=\"20\"><span style=\"color: #ff9900;\"><strong>Managed SharpDX (1.3 Mono-2.10)<\/strong><\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #ff9900;\"><strong>0.002404<\/strong><\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #ff9900;\"><strong>0.001872<\/strong><\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #ff9900;\"><strong>x6.23<\/strong><\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #ff9900;\"><strong>x7.15<\/strong><\/span><\/td>\n<\/tr>\n<tr>\n<td height=\"20\"><span style=\"color: #ff0000;\">M<strong>anaged Windows API CodePack 1.1<\/strong><\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #ff0000;\"><strong>0.002551<\/strong><\/span><\/td>\n<td class=\"xl63\"><span style=\"color: #ff0000;\"><strong>0.003219<\/strong><\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #ff0000;\"><strong>x6.61<\/strong><\/span><\/td>\n<td class=\"xl64\"><span style=\"color: #ff0000;\"><strong>x12.29<\/strong><\/span><\/td>\n<\/tr>\n<tr>\n<td height=\"20\"><\/td>\n<td class=\"xl63\"><\/td>\n<td class=\"xl63\"><\/td>\n<td class=\"xl64\"><\/td>\n<td class=\"xl64\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>And the associated graphs comparison both for x86 and x64 platforms:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx64.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"325\" data-permalink=\"https:\/\/imalogic.com\/blog\/2017\/05\/14\/benchmarking-c-net-direct3d-11-apis-vs-native-c\/resultsx64\/\" data-orig-file=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx64.png?fit=526%2C473&amp;ssl=1\" data-orig-size=\"526,473\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Resultsx64\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx64.png?fit=526%2C473&amp;ssl=1\" class=\"alignnone wp-image-325 size-full\" src=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx64.png?resize=526%2C473&#038;ssl=1\" alt=\"\" width=\"526\" height=\"473\" loading=\"lazy\" srcset=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx64.png?w=526&amp;ssl=1 526w, https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx64.png?resize=300%2C270&amp;ssl=1 300w\" sizes=\"auto, (max-width: 526px) 100vw, 526px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx86.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"326\" data-permalink=\"https:\/\/imalogic.com\/blog\/2017\/05\/14\/benchmarking-c-net-direct3d-11-apis-vs-native-c\/resultsx86\/\" data-orig-file=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx86.png?fit=526%2C473&amp;ssl=1\" data-orig-size=\"526,473\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Resultsx86\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx86.png?fit=526%2C473&amp;ssl=1\" class=\"alignnone wp-image-326 size-full\" src=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx86.png?resize=526%2C473&#038;ssl=1\" alt=\"\" width=\"526\" height=\"473\" loading=\"lazy\" srcset=\"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx86.png?w=526&amp;ssl=1 526w, https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/Resultsx86.png?resize=300%2C270&amp;ssl=1 300w\" sizes=\"auto, (max-width: 526px) 100vw, 526px\" \/><\/a><\/p>\n<p>Results are pretty self explanatory. Although we can highlight some interesting facts:<\/p>\n<ul>\n<li><b>Managed Direct3D API calls are much slower than native API calls<\/b>, ranging from x1.52 to x10 depending on the API you are using.<\/li>\n<li><b>SharpDX is providing the fastest Direct3D managed API<\/b>, which is ranging only from x1.52 to x2.32 slower than C++, at least 50% faster than any other managed APIs.<\/li>\n<li><b>All other Direct3D managed API are significantly slower<\/b>, ranging from x2.45 to x12.29<\/li>\n<li><b>Running this benchmark with SharpDX and Mono 2.10 is x6 to x7 times slower than SharpDX with Microsoft JIT <\/b>(!)<\/li>\n<\/ul>\n<p>\u00a0<\/p>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>This is a resume from a old post found on internet about benchmarking\u00a0Direct3D 11. If you are working with a<\/p>\n","protected":false},"author":1,"featured_media":328,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7],"tags":[],"class_list":["post-324","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-coding"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/imalogic.com\/blog\/wp-content\/uploads\/2017\/05\/t%C3%A9l%C3%A9chargement.jpg?fit=310%2C163&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8J21V-5e","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts\/324","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/comments?post=324"}],"version-history":[{"count":1,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts\/324\/revisions"}],"predecessor-version":[{"id":485,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/posts\/324\/revisions\/485"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/media\/328"}],"wp:attachment":[{"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/media?parent=324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/categories?post=324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imalogic.com\/blog\/wp-json\/wp\/v2\/tags?post=324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}