Tag: x86

一个目标文件中的代码对齐正在影响另一个目标文件中的函数的性能

我熟悉数据对齐和性能,但我很擅长对齐代码。 我最近开始使用NASM在x86-64汇编中进行编程,并且一直在使用代码对齐来比较性能。 据我所知,NASM插入nop指令来实现代码对齐。 这是我在Ivy Bridge系统上尝试过的function void triad(float *x, float *y, float *z, int n, int repeat) { float k = 3.14159f; int(int r=0; r<repeat; r++) { for(int i=0; i<n; i++) { z[i] = x[i] + k*y[i]; } } } 我正在使用的组件如下。 如果我没有指定对齐,我的性能与峰值相比只有大约90%。 但是,当我将循环前的代码以及两个内部循环对齐到16个字节时,性能会跳跃到96%。 很明显,这种情况下的代码对齐有所不同。 但这是最奇怪的部分。 如果我将最里面的循环对齐到32个字节,那么这个函数的性能没有任何区别,但是,在这个函数的另一个版本中,在单独的目标文件中使用内在函数,我将其性能从90%链接到95%! 我做了一个对象转储(使用objdump -d -M intel )的版本对齐到16个字节(我将结果发布到这个问题的结尾)和32个字节,它们是相同的! 事实certificate,在两个目标文件中,最内层循环无论如何都对齐到32个字节。 但必须有一些区别。 我对每个目标文件进行了hex转储,目标文件中有一个字节不同。 对齐到16个字节的目标文件具有0x10的字节,并且对应于32个字节的目标文件具有0x20的字节。 到底是怎么回事! […]

在C中将32位应用程序转换为64位应用程序

我目前正致力于将32位应用程序转换为C语言中的64位应用程序。此应用程序目前正在开发x86架构(Windows,osx,Unix,Linux)。 因此,在开始编码之前,我想知道在转换应用程序时我需要考虑什么。

这个汇编函数调用安全/完整吗?

我没有assembly经验,但这是我一直在努力的。 如果我缺少传递参数和通过程序集中的指针调用函数的任何基本方面,我想输入。 例如,我想知道我是否应该恢复ecx , edx , esi , edi 。 我读过它们是通用寄存器,但我找不到它们是否需要恢复? 打电话后我应该做什么样的清理工作? 这是我现在的代码,它确实有效: #include “stdio.h” void foo(int a, int b, int c, int d) { printf(“values = %d and %d and %d and %d\r\n”, a, b, c, d); } int main() { int a=3,b=6,c=9,d=12; __asm__( “mov %3, %%ecx;” “mov %2, %%edx;” “mov %1, %%esi;” “mov […]

直接打印到文本video内存时出现意外输出

我正在用C开发一个内核,并在屏幕上创建了一些可以在video内存上打印的内容。 我预计video内存中的第一个字节将是要打印的字符,第二个字节会告诉颜色。 但我的程序有一些不同,但它的工作原理! 这是非常意外和不寻常的。 我的内核代码 – #define VIDEO_MEM 0xb8000 void write_string( int colour, const unsigned char *string ); void main() { unsigned char *vid = (unsigned char*) VIDEO_MEM; int i=0; for (i = 0; i < 2000; i++) { *vid = ' '; *(vid+2) = 0x1f; vid += 2; } write_string(0x1f,"The Kernel has been loaded […]

任何浮点密集型代码是否会在任何基于x86的架构中产生精确的结果?

我想知道使用浮点运算的C或C ++中的任何代码是否会在任何基于x86的体系结构中产生精确的结果,无论代码的复杂程度如何。 据我所知,自英特尔8087以来的任何x86架构都使用准备处理IEEE-754浮点数的FPU单元,我看不出为什么结果在不同架构中会有所不同的任何原因。 但是,如果它们不同(即由于不同的编译器或不同的优化级别),是否可以通过配置编译器来产生位精确结果?

如何在GCC x86中使用RDTSC计算时钟周期?

使用Visual Studio,我可以从处理器读取时钟周期数,如下所示。 我如何与GCC做同样的事情? #ifdef _MSC_VER // Compiler: Microsoft Visual Studio #ifdef _M_IX86 // Processor: x86 inline uint64_t clockCycleCount() { uint64_t c; __asm { cpuid // serialize processor rdtsc // read time stamp counter mov dword ptr [c + 0], eax mov dword ptr [c + 4], edx } return c; } #elif defined(_M_X64) // Processor: […]

at&t asm inline c ++问题

我的代码 const int howmany = 5046; char buffer[howmany]; asm(“lea buffer,%esi”); //Get the address of buffer asm(“mov howmany,%ebx”); //Set the loop number asm(“buf_loop:”); //Lable for beginning of loop asm(“movb (%esi),%al”); //Copy buffer[x] to al asm(“inc %esi”); //Increment buffer address asm(“dec %ebx”); //Decrement loop count asm(“jnz buf_loop”); //jump to buf_loop if(ebx>0) 我的问题 我正在使用gcc编译器。 出于某种原因,我的缓冲区/ howmany变量在我的asm眼中是不确定的。 我不知道为什么。 我只想将缓冲区数组的起始地址移动到esi寄存器中,将每个元素复制到al寄存器时循环“howmany”次。

编译器有时可以缓存声明为volatile的变量

据我所知,编译器从不优化声明为volatile的变量。 但是,我有一个像这样声明的数组。 volatile long array[8]; 不同的线程读写它。 数组的元素仅由其中一个线程修改,并由任何其他线程读取。 但是,在某些情况下,我注意到即使我从一个线程修改一个元素,读取它的线程也不会注意到这个变化。 它继续读取相同的旧值,就好像编译器已将其缓存在某处。 但是编译器本身不应该缓存一个volatile变量,对吗? 那怎么会发生这种情况。 注意 :我没有使用volatile进行线程同步,所以请停止给我答案,比如使用锁或primefaces变量。 我知道volatile,atomic变量和互斥量之间的区别。 另请注意,该体系结构是x86,具有主动缓存一致性。 另外,在我认为变量被其他线程修改之后,我已经读了足够长的时间。 即使经过很长一段时间,阅读线程也看不到修改后的值。

什么是在x86上提供无分支FP min和max的指令?

引用(感谢作者开发和共享算法!): Fast, Branchless Ray/Bounding Box Intersections 由于现代浮点指令集可以在没有分支的情况下计算最小值和最大值 作者的相应代码就是 dmnsn_min(double a, double b) { return a < b ? a : b; } 我熟悉例如_mm_max_ps ,但这是一个向量指令。 上面的代码显然是用于标量forms。 题: 什么是x86上的标量无分支minmax指令? 这是一系列指令吗? 假设它将被应用,或者如何调用它是否安全? 关于min / max的无分支问题是否有意义? 根据我的理解,对于光线跟踪器和/或其他视觉软件,给定光线盒交叉例程,分支预测器没有可靠的模式来拾取,因此消除分支确实有意义。 我是对的吗? 最重要的是,所讨论的算法是围绕(+/-)INFINITY进行比较而建立的。 这是可靠的,我们正在讨论的(未知)指令和浮点标准吗? 以防万一:我熟悉在C ++中使用min和max函数 ,相信它是相关的,但不是我的问题。

什么是近,远和巨大的指针?

任何人都可以用适当的例子向我解释这些指针……当这些指针被使用时?