我们已将VS2013 C++/MFC应用程序移植到VS2015,并且在VS2015编译器生成的性能和代码方面存在一些相当令人不安的问题.
请注意,这是针对x86的.
log10()调用的速度要慢一些.使用CPU采样分析版本构建时,我们发现这些调用比以前占用了更多的时间.从VS2013的同一次运行中的49个样本到VS2015中相同运行的高达7545个样本.这意味着此功能从CPU负载的0.6%变为有问题的应用程序的50%.
在VS2013中,探查器显示:
Function Name Inclusive Samples Exclusive Samples Inclusive Samples % Exclusive Samples %
__libm_sse2_log10 49 49 0.61 0.61
Run Code Online (Sandbox Code Playgroud)
在VS2015中,分析器显示:
Function Name Inclusive Samples Exclusive Samples Inclusive Samples % Exclusive Samples %
___sse2_log102 7,545 7,545 50.43 50.43
Run Code Online (Sandbox Code Playgroud)
为什么不同的功能名称?
我们简要介绍了生成的log10程序集.在VS2013上,这转发给disp_pentium4.inc和log10_pentium4.asm.在VS2015上,这是不同的.似乎VS2015又回到__libm_sse2_log10了Debug中.
这可能__sse2_log102仅仅是造成这种性能差异的原因吗?我们检查了调用它们的函数的结果输出是否在预期的浮点差异内.
我们正在使用目标v140_xp进行编译,并具有以下编译选项:
/Yu"stdafx.h" /MP /GS- /GL /analyze- /W4 /wd"4510" /wd"4610" /Zc:wchar_t /Z7 /Gm- /Ox /Ob2 /Zc:inline /fp:fast /D "WINVER=0x0501" /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_CRT_SECURE_NO_WARNINGS" /D "_CRT_SECURE_NO_DEPRECATE" /D …Run Code Online (Sandbox Code Playgroud) c++ performance visual-c++ visual-studio-2013 visual-studio-2015
为了将项目设置合并到C++和C#项目的属性表中,构造了以下属性表:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
Trying to support both C++ and C# projects by introducing derived
properties and setting the appropriate output properties.
-->
<PropertyGroup Label="UserMacros">
<ProjectOrAssemblyName Condition="'$(AssemblyName)'==''">$(ProjectName)</ProjectOrAssemblyName>
<ProjectOrAssemblyName Condition="'$(ProjectName)'==''">$(AssemblyName)</ProjectOrAssemblyName>
<ShortPlatform Condition="'$(Platform)'=='Win32'">x86</ShortPlatform>
<ShortPlatform Condition="'$(Platform)'=='x86'">x86</ShortPlatform>
<ShortPlatform Condition="'$(Platform)'=='x64'">x64</ShortPlatform>
<ShortPlatform Condition="'$(Platform)'=='AnyCPU'">AnyCPU</ShortPlatform>
</PropertyGroup>
<PropertyGroup>
<OutputPath>$(OutputRelativePath)/$(ProjectOrAssemblyName)_$(ShortPlatform)_$(Configuration)/</OutputPath>
<BaseIntermediateOutputPath>$(OutputRelativePath)/Obj_Exe/$(ProjectOrAssemblyName)_$(ShortPlatform)</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)_$(Configuration)/</IntermediateOutputPath>
<IntDir>$(IntermediateOutputPath)</IntDir>
<OutDir>$(OutputPath)</OutDir>
</PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
此属性表将所有构建输出移动到单独的位置OutputRelativePath(在单独的属性表中定义或直接在项目文件中定义)外部目录,其中包含源代码以便于清理等.但是,在设置完成后,构建工作正常并且所有单元测试工作正常,很明显WPF可执行项目并不好,因为使用上面的属性表运行应用程序导致臭名昭着:
IOException was unhandled "Cannot locate resource 'app.xaml'."
Run Code Online (Sandbox Code Playgroud)
为什么更改输出路径会导致此错误?如何确定原因是项目构建输出路径?这可以在生成的代码中看到吗?我找不到?这不是一个错误吗?
注意:使用以下属性表工作,但仅当IntermediateOutputPath包含BaseIntermediateOutputPath时.
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputPath>$(OutputRelativePath)/$(AssemblyName)_$(Platform)_$(Configuration)</OutputPath>
<BaseIntermediateOutputPath>$(OutputRelativePath)/Obj_Exe/$(AssemblyName)_$(Platform)</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)_$(Configuration)</IntermediateOutputPath>
</PropertyGroup>
</Project> …Run Code Online (Sandbox Code Playgroud) 是否存在将单个.NET程序集拆分为完整程序集子集的实用程序?即ILMerge.exe的"功能逆转"?
当然,如果它必须跟踪类,函数等之间的依赖性等,那么这个工具很难产生.
但是,我正在寻找的情况是我有一个非常大(数百MB)的混合模式程序集,主要是静态类和静态方法,基本上只是一个函数库.虽然,与一些DLLMain初始化和类似.
我想要的是能够在我希望保留在子集程序集中的特定静态类上指定静态方法列表.从技术上讲,这应该是可能的,因为程序集只是具有标准格式的二进制信息.
这是否存在或如何制作?或者为什么这不切实际?
这可能只是一个新手问题,但我有以下几点:
public class FooSettings {}
public class BarSettings {}
public class DohSettings {}
// There might be many more settings types...
public interface IProcessor { ... }
public class FooProcessor
: IProcessor
{
public FooProcessor(FooSettings) { ... }
}
public class BarProcessor
: IProcessor
{
public BarProcessor(BarSettings) { ... }
}
public class DohProcessor
: IProcessor
{
public DohProcessor(DohSettings) { ... }
}
// There might be many more processor types with matching settings...
public interface IProcessorConsumer {}
public class …Run Code Online (Sandbox Code Playgroud) 我们在git中有一些非常大的存储库,在这些中我们已经观察到克隆/拉取时远程/服务器压缩是一个瓶颈.考虑到git已经变得多么普遍,并且使用了zlib,这个zlib压缩是否已经过优化?
英特尔的一篇论文详细介绍了如何在压缩比较小的情况下将DEFLATE压缩速度提高约4倍:
另一篇论文表明,对于大多数压缩'水平'(1-9),压缩比保持在~1.8倍的速度:
后一种优化似乎可以在github上找到:https://github.com/jtkukunas/zlib
zlib似乎已经很老了(在这个快节奏的行业中)最新版本是从2013年4月开始的.有没有尝试过SIMD优化zlib用于新一代处理器?或者有没有替代在git中使用zlib?
我知道你可以在git中指定一个会影响速度和压缩比的压缩级别.但是,上面表明可以在不损害压缩比的情况下对zlib进行相当大的性能改进.
那么回顾一下,是否有任何现有的git实现使用高度优化的zlib或zlib替代方案?
PS:似乎很多开发/服务器都会从中受益(即使是温室气体排放;)).
我在使用WPF时遇到了一些严重问题DrawingContext,或者特别VisualDrawingContext是来自覆盖OnRender元素或使用DrawingVisual.RenderOpen().
问题是这个分配很多.例如,byte[]每次使用绘图上下文时,似乎都在分配 缓冲区.
关于如何使用绘图上下文的示例.
using (var drawingContext = m_drawingVisual.RenderOpen())
{
// Many different drawingContext.Draw calls
// E.g. DrawEllipse, DrawRectangle etc.
}
Run Code Online (Sandbox Code Playgroud)
要么
override void OnRender(DrawingContext drawingContext)
{
// Many different drawingContext.Draw calls
// E.g. DrawEllipse, DrawRectangle etc.
}
Run Code Online (Sandbox Code Playgroud)
这会导致大量分配,从而导致一些不必要的垃圾收集.所以是的,我需要这个,请继续主题:).
在具有零或低托管堆分配数的WPF中绘制的选项有哪些?重用对象很好,但我还没有找到一种方法来做到这一点......或者DependencyProperty在它周围/内部没有问题和分配.
我知道WritableBitmapEx但希望有一个解决方案不涉及光栅化到预定位图,而是适当的"矢量"图形,仍然可以缩放例如.
注意:CPU使用率是一个问题,但远远低于由此引起的巨大垃圾压力.
更新:我正在寻找.NET Framework 4.5+的解决方案,如果在更高版本中有任何东西,例如4.7,可能有助于回答这个问题,那就没问题了.但它适用于桌面.NET Framework.
更新2:两个主要方案的简要说明.所有示例都已经过分析CLRProfiler,并且它清楚地表明由于这个原因而发生了大量分配,这对我们的用例来说是一个问题.请注意,这是用于传达原则而不是确切代码的示例代码.
答:这种情况如下所示.基本上,会显示一个图像,并通过自定义绘制一些叠加图形DrawingVisualControl,然后使用该自定义using (var drawingContext = m_drawingVisual.RenderOpen())来获取绘图上下文,然后通过该绘图进行绘制.绘制了大量的椭圆,矩形和文本.此示例还显示了一些缩放内容,这仅适用于缩放等.
<Viewbox x:Name="ImageViewbox" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid x:Name="ImageGrid" SnapsToDevicePixels="True" …Run Code Online (Sandbox Code Playgroud) 在 WPF 中,我们希望将ttf字体用作嵌入资源,而无需将它们复制或安装到系统中,也无需实际将它们写入磁盘。没有内存泄漏问题。
没有详细说明的解决方案:
由于 WPF 内存泄漏,在这种情况下可用:
只能通过AddFontMemResourceEx在 GDI 中从内存和进程安装字体。由于这会为该过程安装字体,因此它也应该适用于 WPF,但是在FontFamily通过AddFontMemResourceEx. 例如:
var font = new FontFamily("Roboto");
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为它不会给出任何错误,但字体实际上并没有改变,一些行间距和其他指标发生了变化,但由于Segoe UI某种原因字体看起来完全一样。
那么问题是它以及如何使用AddFontMemResourceExWPF 中安装的字体?
PS:这里是 P/Invoke 代码:
const string GdiDllName = "gdi32";
[DllImport(GdiDllName, ExactSpelling= true)]
private static extern IntPtr AddFontMemResourceEx(byte[] pbFont, int cbFont, IntPtr pdv, out uint pcFonts);
public static void AddFontMemResourceEx(string fontResourceName, byte[] bytes, Action<string> log)
{
var handle = AddFontMemResourceEx(bytes, bytes.Length, IntPtr.Zero, …Run Code Online (Sandbox Code Playgroud) 尝试将“视觉上”定义的 Azure Pipeline 转换为 yaml,但遇到了问题。使用“可视化”定义的 Azure Pipeline,在执行手动队列时,您将获得类似于以下的 UI:
请注意此 UI 如何让我们在排队时在代理池之间进行选择。这是我们经常使用的功能。我们这样做是因为我们有用于机器学习的管道。
不幸的是,在切换到基于 yaml 的管道时,您无法选择代理池。尽管 yaml 管道没有定义池或类似的东西,但它只是消失了。
有没有办法为基于 yaml 的管道的代理池获取相同类型的下拉框?
更新:使用变量作为池名称是可能的,但也很麻烦,因此不要寻找需要在排队时输入完整池名称的解决方案。因此,要么是下拉框,要么是其他一些机制。
它看起来不像C++/CLI中的System命名空间中对Action和Func委托的支持.至少不适用于多个通用参数,例如:
System::Action<int, int>^ action = nullptr;
System::Func<int, int>^ func = nullptr;
Run Code Online (Sandbox Code Playgroud)
两者都会导致错误,例如:
error C2977: 'System::Action' : too many generic arguments
error C2955: 'System::Action' : use of class generic requires generic argument list
Run Code Online (Sandbox Code Playgroud)
只有单个参数Action有效:
System::Action<int>^ action = nullptr;
Run Code Online (Sandbox Code Playgroud)
任何人,知道为什么或缺少什么来使这项工作.我正在使用Visual Studio 2008,该项目有目标框架3.5.
我在命令行上使用MSBuild在构建服务器上的C#项目的嵌入资源有问题.在Visual Studio中构建和运行测试时,该项目工作得很好,但是当从命令行运行MSBuild时,运行测试时会出现以下问题:
System.Resources.MissingManifestResourceException:找不到适合指定文化或中性文化的任何资源.确保".Properties.Resources.resources"在编译时正确嵌入或链接到程序集"",或者所有所需的附属程序集都是可加载和完全签名的.
System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture,Boolean)中的System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo文化,Dictionary`2 localResourceSets,Boolean tryParents,Boolean createIfNotExists,StackCrawlMark和stackMark)中的System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(String fileName)位于System.Resources.get_SomeResource()的System.Resources.ResourceManager.GetString(String name,CultureInfo culture)的System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture,Boolean createIfNotExists,Boolean tryParents)中的createIfNotExists,Boolean tryParents,StackCrawlMark和stackMark\Properties\Resources.Designer.cs:第87行
我已将问题跟踪到生成的IL(我使用ildasm).在Visual Studio中进行扩展时,在程序集的清单中设置以下内容:
.mresource public <PROJECTNAME>.Properties.Resources.resources
{
// Offset: 0x00000000 Length: 0x00000236
}
Run Code Online (Sandbox Code Playgroud)
但是在使用MSBuild构建时会生成以下输出:
.mresource public '../..//Build/<PROJECTNAME>_AnyCPU_Debug_Obj/<PROJECTNAME>.Properties.Resources.resources'
{
// Offset: 0x00000000 Length: 0x00000236
}
Run Code Online (Sandbox Code Playgroud)
因为可以看到资源的路径突然成为资源名称的一部分.
有没有人有任何想法如何解决这个问题?
与How to mutate a boxed struct using IL 有关,我正在尝试以通用方式更改盒装值类型的值,因此尝试实现以下方法:
void MutateValueType<T>(object o, T v) where T : struct
Run Code Online (Sandbox Code Playgroud)
所以以下应该是可能的:
var oi = (object)17;
MutateValueType<int>(oi, 43);
Console.WriteLine(oi); // 43
var od = (object)17.7d;
MutateValueType<double>(od, 42.3);
Console.WriteLine(od); // 42.3
Run Code Online (Sandbox Code Playgroud)
我无法让它在 .NET Framework 上运行(请参阅 @hvd 的评论,该实现没有typeof(Program).Module适用于其他运行时)。我已经实现了这一点,如下所示。但是,使用以下命令调用委托时会失败del:
System.Security.VerificationException: 'Operation could destabilize the runtime.'
Run Code Online (Sandbox Code Playgroud)
这是我提出的实现:
public static void MutateValueType<T>(object o, T v)
{
var dynMtd = new DynamicMethod("EvilMutateValueType",
typeof(void), new Type[] { typeof(object), typeof(T) });
var il = dynMtd.GetILGenerator(); …Run Code Online (Sandbox Code Playgroud) 比方说你有一个Type叫做primitiveType用primitiveType.IsPrimitive == true,你怎么能最succintly(不使用第三方库)创建的这个实例与非零值(例如,值= 1)?
也就是说,该功能可能如下所示:
public static object CreateNonZero(Type primitiveType)
{
if (!primitiveType.IsPrimitive)
{ throw new ArgumentException("type must be primitive"); }
// TODO
}
Run Code Online (Sandbox Code Playgroud)
也就是说,它应该适用于所有原始值类型,例如bool,byte,sbyte,short,ushort,int,uint,long,ulong,float,double,IntPtr,UIntPtr,char等.
c# ×8
.net ×3
performance ×3
wpf ×3
il ×2
msbuild ×2
.net-3.5 ×1
autofac ×1
azure-devops ×1
c++ ×1
c++-cli ×1
cil ×1
deflate ×1
delegates ×1
fonts ×1
gdi ×1
generics ×1
git ×1
ilmerge ×1
mixed-mode ×1
ninject ×1
optimization ×1
reflection ×1
structuremap ×1
visual-c++ ×1
xaml ×1
zlib ×1