小编Hag*_*gai的帖子

VS2010 .NET内存分析 - 非常慢

运行VS2010的.NET内存分配分析需要很长时间才能完成.

该程序本身运行约3分钟,并产生35GB的内存分配.探查器的输出文件大约为28GB.报告分析过程花了三个多小时(在具有8GB RAM的双Xeon上)完成.

每次我运行内存分析器时都会发生这种情况.
这是您使用此工具的经历吗?
有什么办法可以加快这个过程吗?

谢谢!

.net profiler memory-management visual-studio-2010

20
推荐指数
1
解决办法
2024
查看次数

了解VS2010 C#并行分析结果

我有一个程序有很多独立的计算,所以我决定并行化它.

我使用Parallel.For/Each.

双核机器的结果还可以 - 大多数时候CPU利用率约为80%-90%.但是,使用双Xeon机器(即8个内核),我只获得了大约30%-40%的CPU利用率,尽管该程序在并行部分上花费了相当多的时间(有时超过10秒),我看到它使用了与串行部分相比,这些部分中大约有20-30个线程.每个线程需要1秒以上才能完成,所以我认为它们没有理由不能并行工作 - 除非存在同步问题.

我使用了VS2010的内置分析器,结果很奇怪.即使我只在一个地方使用锁,分析器报告大约85%的程序时间用于同步(也是5-7%睡眠,5-7%执行,低于1%IO).

锁定的代码只是一个缓存(字典)get/add:

bool esn_found;
lock (lock_load_esn)
    esn_found = cache.TryGetValue(st, out esn);
if(!esn_found)
{
    esn = pData.esa_inv_idx.esa[term_idx];
    esn.populate(pData.esa_inv_idx.datafile);
    lock (lock_load_esn)
    {
        if (!cache.ContainsKey(st))
            cache.Add(st, esn);
    }
}
Run Code Online (Sandbox Code Playgroud)

lock_load_esn是Object类型的静态成员.
esn.populate使用单独的StreamReader为每个线程从文件中读取.

但是,当我按下同步按钮以查看导致最大延迟的原因时,我看到探查器报告的是作为功能入口线的线,并且不报告锁定的部分本身.
它甚至没有报告包含上述代码的功能(提醒 - 程序中唯一的锁定)作为阻塞配置文件的一部分,噪声级别为2%.当噪音水平为0%时,它会报告程序的所有功能,我不明白为什么它们被视为阻塞同步.

所以我的问题是 - 这里发生了什么?
85%的时间花在同步上怎么样?
如何找出程序中并行部分的实际问题?

谢谢.

更新:深入研究线程(使用极其有用的可视化工具)后,我发现大部分同步时间都花在等待GC线程完成内存分配上,并且由于通用数据结构调整大小操作需要频繁的分配.

我将不得不看看如何初始化我的数据结构,以便它们在初始化时分配足够的内存,可能避免GC线程的这种竞争.

我今天晚些时候会报告结果.

更新:看起来内存分配确实是问题的原因.当我在并行执行的类中使用所有词典和列表的初始容量时,同步问题更小.我现在只有大约80%的同步时间,CPU利用率达到70%(先前的峰值仅为40%左右).

我进一步钻进每个线程,发现现在很多调用GC分配用于分配不属于大字典的小对象.

我通过为每个线程提供一个预先分配的这类对象池来解决这个问题,我使用它而不是调用"new"函数.

所以我基本上为每个线程实现了一个单独的内存池,但是以非常粗糙的方式,这非常耗时,实际上并不是很好 - 我仍然需要使用很多新的来初始化这些对象,只有现在我全局执行一次,即使不得不增加池的大小,GC线程上的争用也会减少.

但这绝对不是我喜欢的解决方案,因为它不容易推广,我不想写自己的内存管理器.
有没有办法告诉.NET为每个线程分配预定义的内存量,然后从本地池中获取所有内存分配?

c# parallel-processing profiling visual-studio-2010

15
推荐指数
1
解决办法
1263
查看次数

如何故意过度装配Weka树分类器?

我有一个二进制类数据集(0/1),向"0"类倾斜很大(大约30000对1500).每个实例有7个功能,没有缺失值.

当我使用J48或任何其他树分类器时,我几乎将所有"1"实例错误分类为"0".

将分类器设置为"未分级",将每个叶子的最小实例数设置为1,将置信因子设置为1,添加具有实例ID号的虚拟属性 - 所有这些都无济于事.

我只是无法创建一个过度拟合数据的模型!

我也尝试了几乎所有Weka提供的其他分类器,但得到了类似的结果.

使用IB1获得100%的准确度(列车集上的列车集),因此不存在具有相同特征值和不同类别的多个实例的问题.

如何创建完全未修剪的树?或者强迫Weka过度填充我的数据?

谢谢.

更新:好的,这很荒谬.我只使用了大约3100个负面例子和1200个正面例子,这是我得到的树(未修剪!):

J48 unpruned tree
------------------

F <= 0.90747: 1 (201.0/54.0)
F > 0.90747: 0 (4153.0/1062.0)
Run Code Online (Sandbox Code Playgroud)

不用说,IB1仍然提供100%的精度.

更新2:不知道我是如何错过它的 - 未经训练的SimpleCart工作并且在火车上提供100%准确度的训练; 修剪过的SimpleCart并不像J48那样有偏见,并且具有不错的误报率和负面比率.

machine-learning weka

7
推荐指数
2
解决办法
3190
查看次数

在C#中优化稀疏点积

我正在尝试计算两个非常稀疏的关联数组的点积.数组包含ID和值,因此只应对两个数组共有的ID进行计算,例如

[(1, 0.5), (3, 0.7), (12, 1.3)] * [(2, 0.4), (3, 2.3), (12, 4.7)] = (0.7 * 2.3) + (1.3 * 4.7)
Run Code Online (Sandbox Code Playgroud)

我的实现(称之为dict)目前使用Dictionaries,但它的速度太慢了.

double dot_product(IDictionary<int, double> arr1, IDictionary<int, double> arr2)
  {
     double res = 0;
     double val2;
     foreach (KeyValuePair<int, double> p in arr1)
        if (arr2.TryGetValue(p.Key, out val2))
           res += p.Value * val2;
     return res;
  }
Run Code Online (Sandbox Code Playgroud)

完整数组每个都有大约500,000个条目,而稀疏数组每个只有几十到几百个条目.

我做了一些玩具版点产品的实验.首先,我试图将两个双阵列相乘,看看我能得到的最终速度(让我们称之为" 平坦 ").

然后我尝试使用int[] ID数组double[] 值数组更改关联数组乘法的实现,在两个ID数组上一起移动并在它们相等时相乘(让我们称之为" double ").

然后,我尝试使用F5Ctrl- 运行所有三个版本的调试或发布F5.结果如下: …

c# optimization

5
推荐指数
1
解决办法
2289
查看次数

对象的C#包装器

我正在寻找一种为任何对象创建通用包装器的方法.
包装器对象的行为就像它包装的类一样,但是可以有更多的属性,变量,方法等,例如对象计数,缓存等.

假设包装类叫做Wrapper,要包装的类叫做Square,并且有构造函数Square(double edge_len)和属性/方法EdgeLengthArea,我想用它如下:

Wrapper<Square> mySquare = new Wrapper<Square>(2.5);  /* or */ new Square(2.5);
Console.Write("Edge {0} -> Area {1}", mySquare.EdgeLength, mySquare.Area);
Run Code Online (Sandbox Code Playgroud)

显然我可以为我想要包装的每个类创建一个这样的包装类,但我正在寻找一个通用的解决方案,即Wrapper<T>可以处理原始类型和复合类型(尽管在我目前的情况下,我会很高兴只包装我自己的类).

建议?

谢谢.

c# wrapper

5
推荐指数
1
解决办法
7017
查看次数

C#中的每线程内存管理

继续从了解VS2010 C#并行性能分析结果的讨论,但更重要的是:

我有许多并行工作的线程(使用Parallel.For/Each),它们为小类使用许多内存分配.

这会在全局内存分配器线程上产生争用.

有没有办法指示.NET为每个线程预分配内存池并从该池中进行所有分配?

目前我的解决方案是我自己的内存池实现(全局分配的类型为T的对象数组,它们在线程中循环使用)这有很大帮助,但效率不高,因为:

  1. 我不能指示.NET从特定的内存片分配.
  2. 我仍然需要多次调用new来为池分配内存.

谢谢,
哈该

c# parallel-processing memory-management contention

4
推荐指数
1
解决办法
5276
查看次数