Tag: 优化

GCC的尾部呼叫优化有多“聪明”?

我刚刚讨论了以下两个C代码的讨论: for循环: #include #define n (196607) int main() { long loop; int count=0; for (loop=0;loop<n;loop++) { count++; } printf("Result = %d\n",count); return 0; } 递归: #include #define n (196607) long recursive(long loop) { return (loop>0) ? recursive(loop-1)+1: 0; } int main() { long result; result = recursive(n); printf(“Result = %d\n”,result); return 0; } 在看到这段代码时,我看到了recursive(loop-1)+1并认为“啊,这不是尾调用递归”,因为它在完成对recursive的调用之后还有工作要做; 它需要增加返回值。 […]

在`C`函数中定义`static const` SIMD变量

我有这种forms的函数(使用SSE从指数函数的最快实现 ): __m128 FastExpSse(__m128 x) { static __m128 const a = _mm_set1_ps(12102203.2f); // (1 << 23) / ln(2) static __m128i const b = _mm_set1_epi32(127 * (1 << 23) – 486411); static __m128 const m87 = _mm_set1_ps(-87); // fast exponential function, x should be in [-87, 87] __m128 mask = _mm_cmpge_ps(x, m87); __m128i tmp = _mm_add_epi32(_mm_cvtps_epi32(_mm_mul_ps(a, […]

(n – 乘法)vs(n / 2 – 乘法+2加法)哪个更好?

我有一个C程序有n次乘法(单次乘法,n次迭代),我发现另一个逻辑有n / 2次迭代(1次乘法+2次加法)。 我知道两者都是O(n)的复杂性。 但就CPU周期而言。 哪个更快?

Clang互惠1次优化

在与同事讨论之后,我最终测试了是否clang如果将两个分区(相当于1)优化为单个分​​区。 const float x = a / b; //x not used elsewhere const float y = 1 / x; 理论上clang可以优化到const float y = b / a如果x仅用作临时步长值,不是吗? 这是一个简单测试用例的输入和输出: https : //gist.github.com/Jiboo/d6e839084841d39e5ab6 (在两个输出中你可以看到它正在执行两个部分,而不是优化) 这个相关的问题是我理解的背后,似乎只关注为什么没有使用特定的指令,而在我的情况下,它是未完成的优化: 为什么GCC或Clang在快速使用时不能优化1指令的倒数-数学 谢谢,JB。

arrays会发生什么

我有一大块代码,用于获取数组并完成它。 在当前项目中,只有一个元素,所以不是将变量更改为char,而是将其声明为char数组[1]。 这样我就不需要修改我的代码并冒险添加任何错误,并且如果需求增长,可以轻松增加它。 它似乎编译好了,但我已经对引擎盖下发生的事情感到好奇,我在浪费记忆吗? 这是否会增加额外的处理时间,编译器会将它全部优化掉,所以如果我输入它会没有什么不同吗? 任何人都可以用这种方式解释使用数组的任何可能的缺点。 我使用c和c ++,它们之间有什么不同吗?

用于C / C ++的JIT优化器

我正在阅读有关JIT优于预编译的优点,其中之一是JIT可以根据实际运行时数据调整分支预测。 现在我在大学写一个编译器已经很久了,但在我看来,在大多数情况下(没有明确的getos),预编译代码也可以实现类似的东西。 请考虑以下代码: test x jne L2: L1: … jmp L3: L2: … L3: 如果我们有一些运行时检测可以看到’jne L2’为真的次数,它可以物理地交换L1:block和L2:block中的所有指令。 当然,它必须知道交换期间任何一个块都没有线程,但这些都是细节…… test x jeq L1: L2: … jmp L3: L1: … L3: 我知道程序代码加载到只读内存等时也存在问题,但这是一个想法。 所以我的问题是,这样的JIT优化是否适用于C / C ++,还是我错过了一些无法做到这一点的根本原因? 那里有C / C ++的JIT优化器吗?

编译成更快的代码:“n * 3”或“n +(n * 2)”?

编译成更快的代码:“ans = n * 3”或“ans = n +(n * 2)”? 假设n是int或long,它是在现代Win32 Intel盒子上运行的。 如果涉及一些解除引用,这会有所不同,也就是说,哪一个会更快? 长的; long * pn; 长的; … * pn = some_number; ans = * pn * 3; 要么 ans = * pn +(* pn * 2); 或者,它是否需要不用担心,因为优化编译器在任何情况下都可能解释这一点?

声明指向const的指针或指向const的const指针作为forms参数

我最近对代码进行了一些调整,其中我不得不在函数中更改forms参数。 最初,参数类似于以下(注意,结构是之前的typedef): static MySpecialStructure my_special_structure; static unsigned char char_being_passed; // Passed to function elsewhere. static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere. int myFunction (MySpecialStructure * p_structure, unsigned char useful_char) { … } 之所以进行更改,是因为我可以在编译时定义并初始化my_special_structure,而myFunction从未更改过它的值。 这导致了以下变化: static const MySpecialStructure my_special_structure; static unsigned char char_being_passed; // Passed to function elsewhere. static MySpecialStructure * p_my_special_structure; // Passed […]

欺骗将常数(2的幂)除以整数

注意这是一个理论问题。 我很满意我的实际代码的性能。 我只是想知道是否有其他选择。 是否有一个技巧可以通过整数变量值对整数除以整数变量值进行整数除法,而不必使用实际的除法运算? // The fixed value of the numerator #define SIGNAL_PULSE_COUNT 0x4000UL // The division that could use a neat trick. uint32_t signalToReferenceRatio(uint32_t referenceCount) { // Promote the numerator to a 64 bit value, shift it left by 32 so // the result has an adequate number of bits of precision, and divide […]

C / C ++编译器反馈优化

有没有人看过任何使用C / C ++编译器提供的反馈优化来支持分支预测,缓存预加载等function的程序的真实世界数字。 我搜索了它,令人惊讶的是,甚至流行的翻译开发小组似乎都没有检查过这种效果。 并且将ruby,python,php等性能提高10%左右应该被认为是有用的。 真的没有任何好处,或整个开发者社区只是懒得使用它?