我目前正在开发一个性能非常关键的程序,我决定探索一条可能有助于减少资源消耗的途径,那就是增加工作线程的堆栈大小,以便将我将要访问的大部分数据(float[])移动到堆栈上(使用stackalloc).

我有read,线程的默认堆栈大小是1MB,所以为了移动所有的float[],我必须将堆栈扩展大约50倍(到50MB~).

我知道这通常被认为是"不安全的",不推荐使用,但在对照这种方法对我当前的代码进行基准测试后,我发现处理速度提高了530%!因此,我不能在没有进一步调查的情况下简单地通过这个选项,这就引出了我的问题;将烟囱增加到如此大的尺寸会有什么危险(可能会出现什么问题),我应该采取什么预防措施来尽量减少这种危险?

我的测试代码,

public static unsafe void TestMethod1()
{
    float* samples = stackalloc float[12500000];

    for (var ii = 0; ii < 12500000; ii++)
    {
        samples[ii] = 32768;
    }
}

public static void TestMethod2()
{
    var samples = new float[12500000];

    for (var i = 0; i < 12500000; i++)
    {
        samples[i] = 32768;
    }
}

推荐答案

在将测试代码与Sam进行比较后,我确定我们都是对的

  • 访问内存(读写)在任何地方都是just as fast—堆栈、全局或堆.
  • 然而,它在堆栈上速度最快,在堆上速度最慢.

它是这样的:stack<;global<;heap.(分配时间)

不过,我强烈建议大家在这件事上要小心

  1. 当您需要频繁创建从不leave函数的数组时(例如,通过传递其引用),使用堆栈将是一个巨大的改进.
  2. 如果你能回收一个数组,那就尽可能地回收!堆是长期存储对象的最佳场所.(污染全局内存不好;堆栈帧可能会消失)

(Note:1.仅适用于值类型;引用类型将在堆上分配,并且好处将减少到0)

回答问题本身:我在任何大型堆栈测试中都没有遇到任何问题

The section below is my initial answer. It is wrong-ish and the tests aren't correct. It is kept only for reference.


我的测试表明,堆栈分配的内存和全局内存在数组中的使用速度至少比堆分配的内存慢15%(需要120%的时间)!

This is my test code,以下是示例输出:

Stack-allocated array time: 00:00:00.2224429
Globally-allocated array time: 00:00:00.2206767
Heap-allocated array time: 00:00:00.1842670
------------------------------------------
Fastest: Heap.

  |    S    |    G    |    H    |
--+---------+---------+---------+
S |    -    | 100.80 %| 120.72 %|
--+---------+---------+---------+
G |  99.21 %|    -    | 119.76 %|
--+---------+---------+---------+
H |  82.84 %|  83.50 %|    -    |
--+---------+---------+---------+
Rates are calculated by dividing the row's value to the column's.

我在Windows 8.1 Pro(带更新1)上测试,使用的是i7 4700 MQ,在.NET 4.5.1下
我使用x86和x64进行了测试,结果是相同的.

Edit:我将所有线程的堆栈大小增加到201MB,样本大小增加到5000万,并将迭代次数减少到5次

Stack-allocated array time: 00:00:00.4504903
Globally-allocated array time: 00:00:00.4020328
Heap-allocated array time: 00:00:00.3439016
------------------------------------------
Fastest: Heap.

  |    S    |    G    |    H    |
--+---------+---------+---------+
S |    -    | 112.05 %| 130.99 %|
--+---------+---------+---------+
G |  89.24 %|    -    | 116.90 %|
--+---------+---------+---------+
H |  76.34 %|  85.54 %|    -    |
--+---------+---------+---------+
Rates are calculated by dividing the row's value to the column's.

尽管如此,这个堆栈似乎实际上是getting slower个.

.net相关问答推荐

如何在AutoMapper中添加自定义方法到项目中?

使用React路由加载器获取数据不能正常工作

无法使用 int.Parse 从字符串转换值

无法解析此引用.找不到程序集

如何使用 C# 关键字作为属性名称?

Owin Twitter登录-根据验证程序远程证书无效

为什么 Any() 不适用于 c# null 对象

ASP.NET MVC:隐藏字段值不会使用 HtmlHelper.Hidden 呈现

发布版本中的 Debug.WriteLine

使用泛型装箱和拆箱

如何根据新的安全策略在 .Net 中发送邮箱?

有没有办法只在 C# 中设置一次属性

如何比较 C# 中的(目录)路径?

如何保护我的 .NET 程序集免受反编译?

使用 XmlDocument 读取 XML 属性

使用语句与最终try

是否可以在 XP 上运行 .NET 4.5 应用程序?

更改 SqlConnection 超时

SqlBulkCopy 的推荐批量大小是多少?

通过继承扩展枚举