Search code examples
c#.net-4.5intel-mklstack-size

Increase stack size of main program or create a new thread with larger stack size for recursive code blocks?


I've a following up question to What is the stack size of a BackgroundWorker DoWork Thread? Is there way to change it?

Should I increase the stack size of my main program using the following post build event:

"$(DevEnvDir)..\..\VC\bin\editbin.exe" /STACK:8388608 "$(TargetPath)"

or should I capsule my recursive code block inside a new thread with a larger stack size?

Thread thread = new Thread(delegate()
{
    // do work with larger stack size
}, 8192 * 1024);
thread.Start();
thread.Join();

The code which has a lot of recursion is from Intel MKLs the LAPACKE_dtrtri function which I call over DLLImport. So I cannot change this code. I can just change the stack size to avoid a stack overflow error.

  • What is the draw back of assign a larger stack size to my main program?

  • What is the draw back of creating a new thread with a larger stack size for this calculation?

  • Which solution is the better one?

  • What would be a reasonable stack size? 8 MB, 16 MB, 32 MB or 64 MB (like MATLAB)? The program runs on computers which have at least 16 GB of RAM (up to 256 GB).

Note: for 99% of my application the default stack size of 4 MB (64-bit) would be enough but the other 1% is using external code which is heavily recursive.


Solution

    • Which solution is the better one?
    • Which solution is the better one?

    The first approach using editbin in a post-build event is failing when using strong name key to sign the assembly. After the assembly was changed using editbin the verification of the signed assembly will fail. sn.exe -v assembly.exe will return Failed to verify assembly -- Strong name validation failed ...

    See as well:

    Using the AfterCompile event and resigning the assembly is a workaround (which I'm using now). The project file should contain the following lines:

      <Target Name="AfterCompile">
        <Exec Command="
    &quot;$(DevEnvDir)..\..\VC\bin\editbin.exe&quot; /STACK:16777216 &quot;$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)&quot;
    &quot;$(FrameworkSDKDir)bin\NETFX 4.5.1 Tools\sn.exe&quot; -Ra &quot;$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)&quot; &quot;$(SolutionDir)\STRONGNAME.snk&quot;
    " />
      </Target>
      <PropertyGroup>
        <PostBuildEvent>REM "See AfterCompile for stack size and resigning"</PostBuildEvent>
      </PropertyGroup>
    

    I was getting aware of the after compile event when I was reading the following answer: https://stackoverflow.com/a/22617361/7556646

    The second approach but for the hole program and not only for the recursive code blocks would look like that:

    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Thread thread = new Thread(delegate()
            {
                Main2(args);
            }, 16 * 1024 * 1024);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
        }
    
        static void Main2(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(app);
        }
    }
    

    The second approach has the drawback that the stack size of a BackgroundWorker DoWork event is still 1 MB (32-bit or any) or 4 MB (64-bit).

    See as well:

    • What is the draw back of creating a new thread with a larger stack size for this calculation?
    • What would be a reasonable stack size?

    See the comments from Hans Passant.