Recently, I have been doing profiling, and I came across one case that turns me nuts. The following is a snippet of unsafe C # code that basically copies the source fetch buffer to the target buffer with a different sample rate. As of now, it takes ~ 0.17% of the total processing time per frame. I do not understand that if I use float instead of double, the processing time will increase to 0.38%. Can someone explain what is going on here?
Fast version (~ 17%)
double rateIncr = ... double readOffset = ... double offsetIncr = ... float v = ... // volume // Source and target buffers. float* src = ... float* tgt = ... for( var c = 0; c < chunkCount; ++c) { for( var s = 0; s < chunkSampleSize; ++s ) { // Source sample var iReadOffset = (int)readOffset; // Interpolate factor var k = (float)readOffset - iReadOffset; // Linearly interpolate 2 contiguous samples and write result to target. *tgt++ += (src[ iReadOffset ] * (1f - k) + src[ iReadOffset + 1 ] * k) * v; // Increment source offset. readOffset += offsetIncr; } // Increment sample rate offsetIncr += rateIncr; }
Slow Version (~ 38%)
float rateIncr = ... float readOffset = ... float offsetIncr = ... float v = ... // volume // Source and target buffers. float* src = ... float* tgt = ... for( var c = 0; c < chunkCount; ++c) { for( var s = 0; s < chunkSampleSize; ++s ) { var iReadOffset = (int)readOffset; // The cast to float is removed var k = readOffset - iReadOffset; *tgt++ += (src[ iReadOffset ] * (1f - k) + src[ iReadOffset + 1 ] * k) * v; readOffset += offsetIncr; } offsetIncr += rateIncr; }
Odd Version (~ 22%)
float rateIncr = ... float readOffset = ... float offsetIncr = ... float v = ... // volume // Source and target buffers. float* src = ... float* tgt = ... for( var c = 0; c < chunkCount; ++c) { for( var s = 0; s < chunkSampleSize; ++s ) { var iReadOffset = (int)readOffset; var k = readOffset - iReadOffset; // By just placing this test it goes down from 38% to 22%, // and the condition is NEVER met. if( (k != 0) && Math.Abs( k ) < 1e-38 ) { Console.WriteLine( "Denormalized float?" ); } *tgt++ += (src[ iReadOffset ] * (1f - k) + src[ iReadOffset + 1 ] * k) * v; readOffset += offsetIncr; } offsetIncr += rateIncr; }
Now i know i don't know anything
64- 32- ? , , , , ( , 64- ). , , 32- ...
, , ++ ( , , ). ++, .
:
MSDN float .NET, float, , CLR float:
x87 FPU. , CLR ( , 80- x87) ( ), . , IL conv.r4 conv.r8 , .
, float , 80- FPU x87 - , . IL, , , , , . , #, fp ++, , .
, , -, . IL , ?
, float "denormal", x86. , . , , .
, , , , , .
http://en.wikipedia.org/wiki/Denormal
, , - x86, . , # , , , - . , , .
, , , JIT . , , , .
, 3 , , , , / .
32- :
// NOTE: runnable - copy in paste into your own project class Program { static int endVal = 32768; static int runCount = 100; static void Main(string[] args) { Stopwatch doublesw = Stopwatch.StartNew(); for (int i = 0; i < runCount; ++i) doubleTest(); doublesw.Stop(); Console.WriteLine("Double: " + doublesw.ElapsedMilliseconds); Stopwatch floatsw = Stopwatch.StartNew(); for (int i = 0; i < runCount; ++i) floatTest(); floatsw.Stop(); Console.WriteLine("Float: " + floatsw.ElapsedMilliseconds); Console.ReadLine(); } static void doubleTest() { double value = 0; double incr = 0.001D; while (value < endVal) { value += incr; } } static void floatTest() { float value = 0; float incr = 0.001f; while (value < endVal) { value += incr; } } } }
Double: 12897 Float: 10059
, . , .
, , , , , , , , () , .
( №3 - - )
, , :
(float)readOffset
float readOffset .
. , , - . , , ?
, , , - , .
I hope that my letter makes sense and is understandable. But in short, if your whole process requires a longer time, the percentage value for this function (which remains constant all the time due to the fact that it will not be changed) will drop.
Source: https://habr.com/ru/post/1708333/More articles:C # How to find the size of a reference type - c #Submitting AjaxForm using jQuery in ASP.NET MVC - jqueryIs there a way to prevent dll from opening in software such as a reflector? - c #Report generation in PHP (pdf, xls, doc, csv format required) - php.NET Application and ASP.NET Domains - .netNightmare Validator with C # Dynamic Management - c #Balancing Algorithm - vectorizationОбновление панелей в ретрансляторах - Почему не может одновременно работать несколько обратных вызовов? - asp.netПитон и коллективный интеллект - pythonhttps://translate.googleusercontent.com/translate_c?depth=1&pto=aue&rurl=translate.google.com&sl=ru&sp=nmt4&tl=en&u=https://fooobar.com/questions/1708338/add-options-to-select-drop-down-in-ie&usg=ALkJrhjLhUUYVvMXAMB264bo0hm-R_mZZgAll Articles