增加主程序的堆栈大小或为递归代码块创建一个具有更大堆栈大小的新线程? [英] Increase stack size of main program or create a new thread with larger stack size for recursive code blocks?
问题描述
我有一个后续问题什么是BackgroundWorker DoWork 线程的堆栈大小?有办法改吗?
我是否应该使用以下构建后事件增加主程序的堆栈大小:
Should I increase the stack size of my main program using the following post build event:
"$(DevEnvDir)....VCineditbin.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();
具有大量递归的代码来自英特尔 MKLs LAPACKE_dtrtri 函数.所以我无法更改此代码.我可以更改堆栈大小以避免堆栈溢出错误.
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?
哪种解决方案更好?
什么是合理的堆栈大小?8 MB、16 MB、32 MB 或 64 MB(例如 MATLAB)?该程序可在至少具有 16 GB RAM(最高 256 GB)的计算机上运行.
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).
注意:对于我的 99% 的应用程序,4 MB(64 位)的默认堆栈大小就足够了,但另外 1% 正在使用高度递归的外部代码.
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.
推荐答案
- 哪种解决方案更好?
- 哪种解决方案更好?
在构建后事件中使用 editbin
的第一种方法在使用强名称密钥对程序集进行签名时失败.使用 editbin
更改程序集后,签名程序集的验证将失败.sn.exe -v assembly.exe
将返回 Failed to verify assembly -- Strong name validation failed ...
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 ...
另见:
使用 AfterCompile
事件并退出程序集是一种解决方法(我现在正在使用).项目文件应包含以下几行:
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="
"$(DevEnvDir)....VCineditbin.exe" /STACK:16777216 "$(ProjectDir)obj$(ConfigurationName)$(TargetFileName)"
"$(FrameworkSDKDir)binNETFX 4.5.1 Toolssn.exe" -Ra "$(ProjectDir)obj$(ConfigurationName)$(TargetFileName)" "$(SolutionDir)STRONGNAME.snk"
" />
</Target>
<PropertyGroup>
<PostBuildEvent>REM "See AfterCompile for stack size and resigning"</PostBuildEvent>
</PropertyGroup>
当我阅读以下答案时,我意识到了 after compile 事件:https://stackoverflow.com/a/22617361/7556646
I was getting aware of the after compile event when I was reading the following answer: https://stackoverflow.com/a/22617361/7556646
第二种方法,但对于hole程序,而不仅仅是递归代码块,看起来像这样:
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);
}
}
第二种方法的缺点是 BackgroundWorker DoWork 事件的堆栈大小仍然是 1 MB(32 位或任何)或 4 MB(64 位).
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).
另见:
- 为此计算创建一个具有更大堆栈大小的新线程有什么缺点?
- 什么是合理的堆栈大小?
查看 Hans Passant 的评论.
See the comments from Hans Passant.
这篇关于增加主程序的堆栈大小或为递归代码块创建一个具有更大堆栈大小的新线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!