Questions tagged «assembly»

汇编语言(asm)编程问题。确保还标记您正在使用的处理器和/或指令集以及汇编器。警告:对于.NET程序集,请使用标签[.net-assembly]。对于Java ASM,请改用标记[java-bytecode-asm]。

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; …

11
用于测试Collat​​z猜想的C ++代码比手写汇编要快-为什么?
我用汇编语言和C ++语言为Euler Q14项目编写了这两种解决方案。它们是用于测试Collat​​z猜想的相同相同的蛮力方法。组装解决方案与 nasm -felf64 p14.asm && gcc p14.o -o p14 C ++使用 g++ p14.cpp -o p14 部件, p14.asm section .data fmt db "%d", 10, 0 global main extern printf section .text main: mov rcx, 1000000 xor rdi, rdi ; max i xor rsi, rsi ; i l1: dec rcx …


4
如何达到每个周期4个FLOP的理论最大值?
在现代的x86-64 Intel CPU上,如何实现每个周期4个浮点运算(双精度)的理论峰值性能? 据我了解,在大多数现代英特尔CPU上,一个SSE 需要三个周期,一个SSE需要add五个周期mul(例如,请参见Agner Fog的“指令表”)。由于流水线,add如果算法具有至少三个独立的求和,则每个循环的吞吐量可以达到一个。由于对于打包addpd以及标量addsd版本和SSE寄存器都可以包含2 double的情况都是如此,每个周期的吞吐量可以高达2触发器。 此外,似乎(虽然我还没有看到任何这适当的文件)add的和mul的可并行给予的四个理论最大吞吐量每个周期触发器执行。 但是,我无法使用简单的C / C ++程序来复制该性能。我的最佳尝试导致每个循环约2.7翻牌。如果有人可以提供一个简单的C / C ++或汇编程序,该程序可以证明其最高性能,将不胜感激。 我的尝试: #include <stdio.h> #include <stdlib.h> #include <math.h> #include <sys/time.h> double stoptime(void) { struct timeval t; gettimeofday(&t,NULL); return (double) t.tv_sec + t.tv_usec/1000000.0; } double addmul(double add, double mul, int ops){ // Need to initialise differently otherwise …

30
什么时候汇编比C更快?
已知的了解汇编器的原因之一是,有时可以用它来编写比用高级语言(尤其是C)编写更高性能的代码。但是,我也听到过很多次声明,尽管这并非完全错误,但实际上可以将汇编程序用于生成性能更高的代码的情况极为罕见,并且需要汇编方面的专业知识和经验。 这个问题甚至都没有涉及到汇编程序指令将是特定于机器且不可移植的,或者汇编程序的任何其他方面。当然,除了汇编语言之外,还有很多了解汇编语言的充分理由,但这只是一个具体的问题,需要征集示例和数据,而不是对汇编语言和高级语言的扩展论述。 谁能提供一些特定的例子,说明使用现代编译器进行汇编比编写良好的C代码要快得多,并且您可以提供带有分析依据的主张吗?我对这些案例的存在很有信心,但是我真的想确切地知道这些案例有多深奥,因为这似乎有些争议。
474 c  performance  assembly 


4
为什么在添加了大小写的情况下,Java开启连续int似乎运行得更快?
我正在研究一些Java代码,这些代码需要高度优化,因为它将在热门函数中运行,这些热点函数在我的主程序逻辑中的许多地方被调用。该代码的一部分涉及将double变量乘以10任意非负数int exponents。获得乘数的一种快速方法(编辑:但不是最快的方法,请参见下面的Update 2)是在switch上exponent: double multiplyByPowerOfTen(final double d, final int exponent) { switch (exponent) { case 0: return d; case 1: return d*10; case 2: return d*100; // ... same pattern case 9: return d*1000000000; case 10: return d*10000000000L; // ... same pattern with long literals case 18: return d*1000000000000000000L; default: …

10
使用GCC生成可读的程序集?
我想知道如何在我的C源文件上使用GCC来转储机器码的助记符版本,以便可以看到我的代码被编译成什么。您可以使用Java来做到这一点,但我无法通过GCC找到一种方法。 我试图在汇编中重新编写C方法,看看GCC如何做到这一点会有很大帮助。
256 c  gcc  assembly 

3
什么是retpoline,它如何工作?
为了减轻对内核或跨进程的内存泄露(在幽灵攻击),Linux内核1将用新的选项进行编译,-mindirect-branch=thunk-extern推出gcc通过一个所谓的执行间接调用retpoline。 这似乎是一个新发明的术语,因为Google搜索仅在最近才使用(通常在2018年全部使用)。 什么是retpoline?它如何防止最近发生的内核信息泄露攻击? 1它不是特定于Linux的-类似或相同的构造似乎被用作其他OS 的缓解策略的一部分。

10
多核汇编语言是什么样的?
曾几何时,例如,编写x86汇编器时,您将需要说明“加载EDX寄存器值为5”,“递增EDX”寄存器等指令。 对于具有4个内核(甚至更多)的现代CPU,在机器代码级别上看起来是否只有4个独立的CPU(即,是否只有4个不同的“ EDX”寄存器)?如果是这样,当您说“增加EDX寄存器”时,由什么决定增加哪个CPU的EDX寄存器?x86汇编器中现在有“ CPU上下文”或“线程”概念吗? 内核之间的通信/同步如何工作? 如果您正在编写操作系统,则通过硬件公开什么机制以允许您计划在不同内核上的执行?这是一些特殊的特权说明吗? 如果您正在为多核CPU编写优化的编译器/字节码VM,那么您需要特别了解x86,以使其生成可在所有内核上高效运行的代码? 对x86机​​器代码进行了哪些更改以支持多核功能?
243 assembly  x86  cpu  multicore  smp 

12
“切换”比“ if”快吗?
是一种switch说法实际上比更快的if声明? 我在带有/Ox标记的Visual Studio 2010的x64 C ++编译器上运行了以下代码: #include <stdlib.h> #include <stdio.h> #include <time.h> #define MAX_COUNT (1 << 29) size_t counter = 0; size_t testSwitch() { clock_t start = clock(); size_t i; for (i = 0; i < MAX_COUNT; i++) { switch (counter % 4 + 1) { case 1: counter += …



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.