小编Joh*_*rer的帖子

为什么在单独的循环中元素添加比在组合循环中快得多?

假设a1,b1,c1,并d1指向堆内存和我的数字代码具有下列核心循环.

const int n = 100000;

for (int j = 0; j < n; j++) {
    a1[j] += b1[j];
    c1[j] += d1[j];
}
Run Code Online (Sandbox Code Playgroud)

该循环通过另一个外for循环执行10,000次.为了加快速度,我将代码更改为:

for (int j = 0; j < n; j++) {
    a1[j] += b1[j];
}

for (int j = 0; j < n; j++) {
    c1[j] += d1[j];
}
Run Code Online (Sandbox Code Playgroud)

在MS Visual C++ 10.0上进行了全面优化编译,在Intel Core 2 Duo(x64)上为32位启用了SSE2,第一个示例需要5.5秒,双循环示例仅需1.9秒.我的问题是:(请参考我在底部的改写问题)

PS:我不确定,如果这有帮助:

第一个循环的反汇编基本上是这样的(这个块在整个程序中重复大约五次):

movsd       xmm0,mmword ptr [edx+18h]
addsd …
Run Code Online (Sandbox Code Playgroud)

c c++ performance vectorization compiler-optimization

2175
推荐指数
9
解决办法
23万
查看次数

为什么编译器内联产生比手动内联更慢的代码?

背景

以C++编写的一个数值软件的以下关键循环基本上将两个对象的成员比较:

for(int j=n;--j>0;)
    asd[j%16]=a.e<b.e;
Run Code Online (Sandbox Code Playgroud)

ab是类ASD:

struct ASD  {
    float e;
    ...
};
Run Code Online (Sandbox Code Playgroud)

我正在调查将此比较放在轻量级成员函数中的效果:

bool test(const ASD& y)const {
    return e<y.e;
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

for(int j=n;--j>0;)
    asd[j%16]=a.test(b);
Run Code Online (Sandbox Code Playgroud)

编译器正在内联这个函数,但问题是,汇编代码会有所不同,导致运行时开销超过10%.我要问:

问题

  1. 为什么编译器会推出不同的汇编代码?

  2. 为什么生产的组件更慢?

编辑: 第二个问题已通过实施@ KamyarSouri的建议(j%16)得到了回答.汇编代码现在看起来几乎相同(请参阅http://pastebin.com/diff.php?i=yqXedtPm).唯一的区别是第18,33,48行:

000646F9  movzx       edx,dl 
Run Code Online (Sandbox Code Playgroud)

材料

此图表显示了我的代码的50个测试的FLOP/s(最多为缩放因子).

在此输入图像描述

用于生成绘图的gnuplot脚本:http://pastebin.com/8amNqya7

编译器选项:

/ Zi/W3/WX-/MP/Ox/Ob2/Oi/Ot/Oy/GL/D"WIN32"/ D"NDEBUG"/ D"_CONSOLE"/ D"_UNICODE"/ D"UNICODE"/ Gm-/EHsc/MT/GS-/Gy/arch:SSE2/fp:exact/Zc:wchar_t/Zc:forScope/Gd/analyze-

链接器选项:/ INCREMENTAL:NO"kernel32.lib""user32.lib""gdi32.lib""winspool.lib""comdlg32.lib""advapi32.lib""shell32.lib""ole32.lib""oleaut32. lib""uuid.lib""odbc32.lib""odbccp32.lib"/ ALLOWISOLATION/MANIFESTUAC:"level ='asInvoker'uiAccess ='false'"/ SUBSYSTEM:CONSOLE/OPT:REF/OPT:ICF/LTCG/TLBID …

c++ performance assembly inlining compiler-optimization

31
推荐指数
1
解决办法
1091
查看次数

动态内存分配 - c ++中基元类型的默认初始化

如果我分配一些原始类型的数组,例如

double *v = new double[10];
Run Code Online (Sandbox Code Playgroud)

我需要知道,数组条目的初始值是什么.

它是在标准或编译器dependend中指定的,我在哪里可以找到它.

谢谢,约翰内斯

c++ memory-management initialization

17
推荐指数
1
解决办法
1822
查看次数

boost :: io_service :: post thread是否安全?

从处理程序中发布新的处理程序是否安全?即可以将io_service::run()post new new Handlers 调用到相同的io_service?

谢谢

c++ thread-safety boost-thread boost-asio

10
推荐指数
1
解决办法
5136
查看次数

向C++应用程序添加GUI的最简单方法

我正在用C++制作一个数字软件,并希望添加一个GUI(主要用于Windows).我知道如何使用Java或.NET等现代语言中的舒适编辑器生成GUI.现在我的问题是为程序添加GUI前端最简单,最舒适的方法是什么.在完全免费的工具选择(开源和可移植性会很好),但请记住,如果GUI是用另一种语言实现的话,需要维护多少样板代码和接口(如C#) .

请不要建议从C++切换整个项目!请注意,该程序不需要C++代码和GUI之间的太多交互.

c++ user-interface programming-languages

8
推荐指数
2
解决办法
3万
查看次数

过程指针,派生类型

以下不在英特尔Fortran XE 2011中编译:

TYPE type1
    procedure(interface1),POINTER::p
END TYPE type1

ABSTRACT INTERFACE 
    integer function interface1(a)
        real,intent(in)::a    
    END function interface1
END INTERFACE
Run Code Online (Sandbox Code Playgroud)

错误:

error #8262: The passed-object dummy argument must be dummy data object with the same declared type as the type being defined.
Run Code Online (Sandbox Code Playgroud)

fortran pointers function-pointers

6
推荐指数
1
解决办法
2977
查看次数

如何避免c ++中多态对象的clone()样板代码

如果我想在C++中克隆一个多态对象(即从一些其他类B派生的A类实例),最简单的方法似乎是给B一个虚拟克隆成员函数,必须被A覆盖并查看像这样

A* clone(){
    return new A(*this);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我发现这个不必要的样板代码,因为如果想要使用C++的运行时多态特性,这几乎总是需要的.怎么能被规避呢?

谢谢

为什么我需要这个:

我的用例可以抽象为以下示例:我有一个class Integral,它评估一些函数的积分.这样做,他们有一个指向该成员的成员class MathFunction.这个抽象类包含一个带有evaluate一个参数的纯虚函数.我想实现我会创建的电源功能class PowFunction : class MathFunction.这个类有一个成员exponent,函数evaluate看起来像这样:

double evaluate(x){
    return pow(x,exponent);
}
Run Code Online (Sandbox Code Playgroud)

如所陈述的部件MathFunctionclass Integral必须是polymorhpic,这就要求它是一个指针.用另一个问题回答评论者的问题.为什么我不想复制MathFunction对象?

我真的希望Integral"拥有"它的MathFunction,这意味着它可以在exponent不改变任何其他Integral对象的MathFunction的情况下改变参数(例如).这意味着每个Integral都需要拥有自己的副本.这需要一个用于MathFunctions的clone()函数,不是吗?

我想到的另一种选择:如果几个Integral对象可以通过指向同一地址的指针共享相同的MathFunction,我可以创建Integral对象的副本而无需复制MathFunction.但在这种情况下,我必须使所有的属性const或某种方式readonly,这也不是很优雅.另外,哪个Integral对象应该处理删除MathFunction对象?

为什么你需要这个:

您是否认真地说,只要您使用多态对象,就不需要复制操作?是什么让多态对象在这方面与其他对象不同?

使用此论证,您还可以将复制构造函数和复制赋值运算符从C++标准中删除!

c++ polymorphism virtual

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

加密算法的抗冲突性如何?

对于在明文/密钥对上工作的给定(对称或非对称)加密算法生成的给定密文,找到产生相同密文的不同明文/密钥对有多难?

两个明文/密钥对导致相同的密文有多难?

导致这个问题的是另一个可能与上述问题无关的问题:

如果您有密文和密钥并希望使用某些解密例程对其进行解密,则例程通常会告诉您密钥是否正确.但它怎么知道呢?它是否在结果明文中寻找某种模式,表明解密是成功的?在一些不同的明文中是否存在另一个关键结果,它包含模式并且还被例程报告为"有效"?

后续问题的灵感来自答案和评论:

如果允许的明文/密钥对限制在以下(或两种)方式中:

1)明文以密钥的KCV(密钥检查值)开始.

2)明文以某些明文/密钥组合的哈希值开始

这会使碰撞发现不可行吗?甚至清楚,这样的明文/密钥存在=

encryption cryptography hash-collision

3
推荐指数
1
解决办法
3961
查看次数