小编Mys*_*ial的帖子

为什么Clang会优化此代码?

代码的目的是找到32位浮点位模式的总数,它代表0到1之间的值.在我看来这应该可行,但由于某种原因,Clang的汇编输出基本上相当于return 0;.

我使用-std=c++1y -Wall -Wextra -pedantic -O2和编译了Clang 3.3和Clang 3.4.1-std=c++1y -Wall -Wextra -pedantic -O3

Clang 3.4使用-O2和-O3优化一切.

Clang 3.3仅使用-O3优化一切.

通过"优化一切",我的意思是这是程序的汇编输出:

main:                                   # @main
    xorl    %eax, %eax
    ret
Run Code Online (Sandbox Code Playgroud)
#include <limits>
#include <cstring>
#include <cstdint>

template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
    TO out;
    std::memcpy(&out, &input, sizeof(TO));
    return out;
}

int main()
{
    uint32_t i = std::numeric_limits<uint32_t>::min();
    uint32_t count = 0;

    while (1)
    {
        float n = punning_cast<float>(i);
        if(n >= 0.0f && n <= 1.0f) …
Run Code Online (Sandbox Code Playgroud)

c++ clang compiler-optimization

51
推荐指数
1
解决办法
3618
查看次数

使用AVX CPU指令:没有"/ arch:AVX"的性能不佳

我的C++代码使用SSE,现在我想改进它以支持AVX可用时.所以我检测AVX何时可用并调用使用AVX命令的函数.我使用Win7 SP1 + VS2010 SP1和带AVX的CPU.

要使用AVX,必须包含以下内容:

#include "immintrin.h"
Run Code Online (Sandbox Code Playgroud)

然后你可以使用内在的AVX函数_mm256_mul_ps,_mm256_add_ps等等.问题是,默认情况下,VS2010产生的代码工作得非常慢,并显示警告:

警告C4752:发现英特尔(R)高级矢量扩展; 考虑使用/ arch:AVX

似乎VS2010实际上不使用AVX指令,而是模仿它们.我添加/arch:AVX到编译器选项并获得了良好的结果.但是这个选项告诉编译器尽可能在任何地方使用AVX命令.所以我的代码可能会崩溃在不支持AVX的CPU上!

所以问题是如何使VS2010编译器生成AVX代码,但只有当我直接指定AVX内在函数时.对于它工作的SSE,我只使用SSE内在函数,它产生SSE代码,没有任何编译器选项,如/arch:SSE.但对于AVX而言,由于某些原因它不起作用.

c++ performance sse visual-studio-2010 avx

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

为什么发出这样复杂的代码来将有符号整数除以2的幂?

当我用VC++ 10编译这段代码时:

DWORD ran = rand();
return ran / 4096;
Run Code Online (Sandbox Code Playgroud)

我得到这个反汇编:

299: {
300:    DWORD ran = rand();
  00403940  call        dword ptr [__imp__rand (4050C0h)]  
301:    return ran / 4096;
  00403946  shr         eax,0Ch  
302: }
  00403949  ret
Run Code Online (Sandbox Code Playgroud)

这是一个干净,简洁,用一个逻辑右移的2的幂代替一个除法.

然而,当我编译这段代码时:

int ran = rand();
return ran / 4096;
Run Code Online (Sandbox Code Playgroud)

我得到这个反汇编:

299: {
300:    int ran = rand();
  00403940  call        dword ptr [__imp__rand (4050C0h)]  
301:    return ran / 4096;
  00403946  cdq  
  00403947  and         edx,0FFFh  
  0040394D  add         eax,edx  
  0040394F  sar         eax,0Ch  
302: }
  00403952  ret …
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly division visual-c++

44
推荐指数
3
解决办法
3147
查看次数

便携式分支预测提示

有没有可行的分支预测提示方法?请考虑以下示例:

  if (unlikely_condition) {
    /* ..A.. */
  } else {
    /* ..B.. */
  }
Run Code Online (Sandbox Code Playgroud)

这有什么不同于:

  if (!unlikely_condition) {
    /* ..B.. */
  } else {
    /* ..A.. */
  }
Run Code Online (Sandbox Code Playgroud)

或者是使用编译器特定提示的唯一方法?(例如海湾合作委员会的__builtin_expect)

编译器会根据if条件的顺序对条件进行不同的处理吗?

c c++ compiler-construction optimization branch-prediction

38
推荐指数
4
解决办法
9589
查看次数

GCC:两个相似循环之间的矢量化差异

在编译时gcc -O3,为什么以下循环没有矢量化(自动):

#define SIZE (65536)

int a[SIZE], b[SIZE], c[SIZE];

int foo () {
  int i, j;

  for (i=0; i<SIZE; i++){
    for (j=i; j<SIZE; j++) {
      a[i] = b[i] > c[j] ? b[i] : c[j];
    }
  }
  return a[0];
}
Run Code Online (Sandbox Code Playgroud)

什么时候呢?

#define SIZE (65536)

int a[SIZE], b[SIZE], c[SIZE];

int foov () {
  int i, j;

  for (i=0; i<SIZE; i++){
    for (j=i; j<SIZE; j++) {
      a[i] += b[i] > c[j] ? b[i] : c[j];
    }
  }
  return a[0];
}
Run Code Online (Sandbox Code Playgroud)

唯一的区别在于内部循环中的表达式的结果是 …

c gcc loops vectorization compiler-optimization

33
推荐指数
1
解决办法
2816
查看次数

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

背景

以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
查看次数

为什么不同整数大小的数组具有不同的性能?

我有以下问题:

写时间到std::array用于int8,int16,int32int64与每个尺寸增加一倍.我可以理解8位CPU的这种行为,但不能理解32/64位.

为什么32位系统需要4倍的时间来保存32位值而不是保存8位值?

这是我的测试代码:

#include <iostream>
#include <array>
#include <chrono>

std::array<std::int8_t, 64 * 1024 * 1024> int8Array;
std::array<std::int16_t, 64 * 1024 * 1024> int16Array;
std::array<std::int32_t, 64 * 1024 * 1024> int32Array;
std::array<std::int64_t, 64 * 1024 * 1024> int64Array;

void PutZero()
{
    auto point1 = std::chrono::high_resolution_clock::now();
    for (auto &v : int8Array) v = 0;
    auto point2 = std::chrono::high_resolution_clock::now();
    for (auto &v : int16Array) v = 0;
    auto point3 = std::chrono::high_resolution_clock::now();
    for …
Run Code Online (Sandbox Code Playgroud)

c++ arrays performance

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

如何实现2D矢量数组?

我是第一次在STL库中使用vector类.我应该如何添加到矢量数组的特定行?

struct x{
     vector <vector <int> > v;
     int row;
 };

vector< int* > my ints;
int add;
Run Code Online (Sandbox Code Playgroud)

如果我想用第一个整数指针添加到第一行v,我能做到吗?

myints[0]->v[myints[0]->row].push_back(add);
Run Code Online (Sandbox Code Playgroud)

这种方法是否可以创建向量ints的二维向量,其中每一行可能具有不同的长度(即具有不同的列数)?

c++ vector

25
推荐指数
5
解决办法
17万
查看次数

哪个更快 - C#不安全代码或原始C++

我正在编写一个图像处理程序来执行视频帧的实时处理.它是在C#中使用包装OpenCV库dll(非托管C++)的Emgu.CV库(C#).现在我必须编写自己的特殊算法,它需要尽可能快.

哪个算法的实现速度更快?

  1. 在C#中编写'不安全'函数

  2. 将该函数添加到OpenCV库并通过Emgu.CV调用它

我猜C#unsafe比较慢,因为它是通过JIT编译器,但差异是否显着?

编辑:

在VS2008下编译为.NET 3.5

c# c++ performance unsafe image-processing

24
推荐指数
4
解决办法
2万
查看次数

返回包含数组的struct

gcc 4.4.4下面的简单代码段错误

#include<stdio.h>

typedef struct Foo Foo;
struct Foo {
    char f[25];
};

Foo foo(){
    Foo f = {"Hello, World!"};
    return f;
}

int main(){
    printf("%s\n", foo().f);
}
Run Code Online (Sandbox Code Playgroud)

将最后一行更改为

 Foo f = foo(); printf("%s\n", f.f);
Run Code Online (Sandbox Code Playgroud)

工作良好.这两个版本在编译时都有效-std=c99.我只是调用未定义的行为,或者标准中的某些内容已更改,这允许代码在C99下工作?为什么在C89下崩溃?

c linux gcc language-lawyer

23
推荐指数
2
解决办法
2732
查看次数