Questions tagged «compiler-optimization»

编译器优化涉及调整编译器以减少运行时或对象大小,或两者兼而有之。这可以通过使用编译器参数(即CFLAGS,LDFLAGS),编译器插件(例如DEHYDRA)或直接对编译器进行修改(例如修改源代码)来实现。

10
为什么单独循环中的元素加法比组合循环中的要快得多?
假设a1,b1,c1,并d1指向堆内存和我的数字代码具有下列核心循环。 const int n = 100000; for (int j = 0; j < n; j++) { a1[j] += b1[j]; c1[j] += d1[j]; } 该循环通过另一个外部for循环执行了10,000次。为了加快速度,我将代码更改为: for (int j = 0; j < n; j++) { a1[j] += b1[j]; } for (int j = 0; j < n; j++) { c1[j] += …

12
GCC为什么不将a * a * a * a * a * a优化为(a * a * a)*(a * a * a)?
我正在对科学应用程序进行一些数值优化。我注意到的一件事是,GCC将pow(a,2)通过将其编译为来优化该调用a*a,但是该调用pow(a,6)并未进行优化,实际上将调用该库函数pow,这大大降低了性能。(相反,可执行文件Intel C ++编译器icc将消除对的库调用pow(a,6)。) 我很好奇的是,当我替换pow(a,6)为a*a*a*a*a*a使用GCC 4.5.1和选项“ -O3 -lm -funroll-loops -msse4”时,它使用5 mulsd条指令: movapd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 而如果我写(a*a*a)*(a*a*a),它将产生 movapd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm13, %xmm13 这将乘法指令的数量减少到3. icc具有相似的行为。 为什么编译器无法识别此优化技巧?

10
将32位循环计数器替换为64位会在Intel CPU上使用_mm_popcnt_u64引起疯狂的性能偏差
我一直在寻找处理popcount大量数据的最快方法。我遇到了一个非常奇怪的效果:将loop变量从更改为unsigned,uint64_t使PC上的性能下降了50%。 基准测试 #include <iostream> #include <chrono> #include <x86intrin.h> int main(int argc, char* argv[]) { using namespace std; if (argc != 2) { cerr << "usage: array_size in MB" << endl; return -1; } uint64_t size = atol(argv[1])<<20; uint64_t* buffer = new uint64_t[size/8]; char* charbuffer = reinterpret_cast<char*>(buffer); for (unsigned i=0; i<size; …

9
Swift Beta性能:对数组进行排序
我在Swift Beta中实现一种算法,发现性能非常差。深入研究后,我意识到瓶颈之一就是对数组进行排序一样简单。相关部分在这里: let n = 1000000 var x = [Int](repeating: 0, count: n) for i in 0..<n { x[i] = random() } // start clock here let y = sort(x) // stop clock here 在C ++中,类似的操作在我的计算机上花费0.06s。 在Python中,它花费0.6秒(绝招,仅y =整数列表的sorted(x))。 在Swift中,如果使用以下命令进行编译,则需要6s: xcrun swift -O3 -sdk `xcrun --show-sdk-path --sdk macosx` 如果使用以下命令进行编译,则最多需要88s: xcrun swift …

6
如果我针对大小而不是速度进行优化,为什么GCC会生成15-20%的更快代码?
我在2009年首先注意到,如果我对大小(-Os)而不是速度(-O2或-O3)进行优化,那么GCC(至少在我的项目和我的机器上)倾向于生成明显更快的代码,而我一直在想为什么。 我设法创建了(相当愚蠢的)代码来显示这种令人惊讶的行为,并且足够小,可以在此处发布。 const int LOOP_BOUND = 200000000; __attribute__((noinline)) static int add(const int& x, const int& y) { return x + y; } __attribute__((noinline)) static int work(int xval, int yval) { int sum(0); for (int i=0; i<LOOP_BOUND; ++i) { int x(xval+sum); int y(yval+sum); int z = add(x, y); sum += z; …

1
假设两个可变引用都不能别名,Rust编译器为什么不优化代码?
据我所知,引用/指针别名会阻碍编译器生成优化代码的能力,因为它们必须确保在两个引用/指针确实是别名的情况下,生成的二进制文件的行为正确。例如,在以下C代码中, void adds(int *a, int *b) { *a += *b; *a += *b; } 当clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)用-O3标志编译时,它发出 0000000000000000 <adds>: 0: 8b 07 mov (%rdi),%eax 2: 03 06 add (%rsi),%eax 4: 89 07 mov %eax,(%rdi) # The first time 6: 03 06 add (%rsi),%eax 8: 89 07 mov %eax,(%rdi) # …

12
如何使用SSE4.2和AVX指令编译Tensorflow?
这是从运行脚本以检查Tensorflow是否正常运行时收到的消息: I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcublas.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcudnn.so.5 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcufft.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcuda.so.1 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcurand.so.8.0 locally W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use …

2
C中的&&&操作
#include <stdio.h> volatile int i; int main() { int c; for (i = 0; i < 3; i++) { c = i &&& i; printf("%d\n", c); } return 0; } 使用编译的上述程序的输出gcc为 0 1 1 使用-Wall或-Waddress选项,gcc发出警告: warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress] c在以上程序中如何进行评估?

3
为什么GCC对于几乎相同的C代码生成如此根本不同的汇编?
在编写优化ftol函数时,我在中发现了一些非常奇怪的行为GCC 4.6.1。首先让我向您展示代码(为清楚起见,我标记了不同之处): fast_trunc_one,C: int fast_trunc_one(int i) { int mantissa, exponent, sign, r; mantissa = (i & 0x07fffff) | 0x800000; exponent = 150 - ((i >> 23) & 0xff); sign = i & 0x80000000; if (exponent < 0) { r = mantissa << -exponent; /* diff */ } else { r …

1
我可以通过给出整数范围来提示优化器吗?
我正在使用一种int类型来存储值。根据程序的语义,该值始终在很小的范围内(0-36)变化,并且int(不是a char)仅由于CPU效率而使用。 似乎可以对这么小的整数范围执行许多特殊的算术优化。这些整数上的许多函数调用可能被优化为一小组“魔术​​”运算,甚至某些函数甚至可能被优化为表查找。 因此,是否可以告诉编译器这int总是在很小的范围内,并且编译器可以进行那些优化?

2
为什么与普通函数相比,编译器可以更好地优化lambda?
The C++ Standard Library (Second Edition)Nicolai Josuttis 在他的书中指出,与普通函数相比,编译器可以更好地优化lambda。 此外,C ++编译器比常规函数更好地优化了lambda。(第213页) 这是为什么? 我认为在进行内联时,应该不再有任何区别。我能想到的唯一原因是,编译器可能具有更好的lambda本地上下文,这样可以做出更多的假设并执行更多的优化。


2
Shapeless中Nat类型的限制
在无形状中,Nat类型表示一种在类型级别编码自然数的方法。例如,这用于固定大小的列表。您甚至可以在类型级别上进行计算,例如,将N元素列表追加到元素列表中,K并获取在编译时已知具有N+K元素的列表。 这种表示是否能够表示较大的数字(例如10000002 53),还是会导致Scala编译器放弃?

5
为什么增强的GCC 6优化器会破坏实用的C ++代码?
GCC 6具有新的优化程序功能:假定该this值始终不为null并基于此进行优化。 现在,值范围传播假定C ++成员函数的this指针为非null。这消除了常见的空指针检查,但也破坏了一些不合格的代码库(例如Qt-5,Chromium,KDevelop)。作为临时解决方法,可以使用-fno-delete-null-pointer-checks。使用-fsanitize = undefined可以识别错误的代码。 变更文档显然将此称为危险,因为它破坏了数量惊人的频繁使用的代码。 为什么这个新假设会破坏实用的C ++代码?粗心或不了解信息的程序员是否有特定的模式依赖于这种特定的未定义行为?我无法想象有人写作,if (this == NULL)因为那太不自然了。

7
为什么编译器不能(或不能)将可预测的加法循环优化为乘法?
这是在阅读Mysticial关于该问题的绝妙答案时想到的一个问题:为什么处理排序数组比未排序数组更快? 涉及的类型的上下文: const unsigned arraySize = 32768; int data[arraySize]; long long sum = 0; 他在回答中解释说,英特尔编译器(ICC)对此进行了优化: for (int i = 0; i < 100000; ++i) for (int c = 0; c < arraySize; ++c) if (data[c] >= 128) sum += data[c]; ...变成这样的东西: for (int c = 0; c < arraySize; ++c) …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.