Tag: x86

获取CPU周期数?

我在SO上看到这篇包含C代码的post来获取最新的CPU周期数: 基于CPU周期计算的C / C ++ Linux x86_64中的分析 有没有办法在C ++中使用这段代码(欢迎使用windows和linux解决方案)? 虽然用C语言编写(而C是C ++的一个子集)但我不太确定这段代码是否适用于C ++项目,如果没有,如何翻译呢? 我使用的是x86-64 EDIT2: 找到此function但无法让VS2010识别汇编程序。 我需要包含任何内容吗? (我相信我必须将uint64_t交换为多long long的窗口……?) static inline uint64_t get_cycles() { uint64_t t; __asm volatile (“rdtsc” : “=A”(t)); return t; } EDIT3: 从上面的代码我得到错误: “错误C2400:’操作码’中的内联汇编语法错误;找到’数据类型’” 有人可以帮忙吗?

在x86和x64上读取同一页面内的缓冲区末尾是否安全?

如果允许在输入缓冲区末尾读取少量数据,那么在高性能算法中发现的许多方法都可以(并且被简化)。 这里,“少量”通常意味着超过结尾的W – 1个字节,其中W是算法的字节大小(例如,对于处理64位块中的输入的算法,最多7个字节)。 很明显, 写入输入缓冲区的末尾通常是不安全的,因为您可能会破坏缓冲区1之外的数据。 同样清楚的是,将缓冲区的末尾读取到另一页面可能会触发分段错误/访问冲突,因为下一页可能不可读。 但是,在读取对齐值的特殊情况下,页面错误似乎是不可能的,至少在x86上是这样。 在该平台上,页面(以及因此内存保护标志)具有4K粒度(较大的页面,例如2MiB或1GiB,可能,但这些是4K的倍数),因此对齐的读取将仅访问与有效页面相同的页面中的字节缓冲区的一部分。 这是一个循环的规范示例,它对齐其输入并在缓冲区末尾读取最多7个字节: int processBytes(uint8_t *input, size_t size) { uint64_t *input64 = (uint64_t *)input, end64 = (uint64_t *)(input + size); int res; if (size = 0) { return input + res; } // align pointer to the next 8-byte boundary input64 = (ptrdiff_t)(input64 + 1) & ~0x7; for […]

如何执行_mm256_movemask_epi8(VPMOVMSKB)的反转?

内在的: int mask = _mm256_movemask_epi8(__m256i s1) 创建一个掩码,其32位对应于s1的每个字节的最高位。 在使用位操作(例如BMI2 )操作掩码之后,我想执行_mm256_movemask_epi8的反转,即创建__m256i向量,其中每个字节的最高有效位包含uint32_t mask的相应位。 做这个的最好方式是什么? 编辑:我需要执行逆操作,因为内部_mm256_blendv_epi8只接受__m256i类型的掩码而不是uint32_t 。 因此,在生成的__m256i掩码中,我可以忽略每个字节的MSB以外的位。

x86_64 ASM – 指令的最大字节数?

完整指令在x64 asm代码中需要的最大字节数是多少? 跳转到地址可能会占用多达9个字节我想: FF 00 00 00 00 11 12 3F 1F但我不知道这是否是x64指令可以使用的最大字节数

为什么GCC编译C程序需要.eh_frame部分?

测试是在32位x86 Linux上使用gcc 4.6.3 当使用gcc编译C程序并使用readelf检查部分信息时,我可以在里面看到.eh_frame部分和.eh_frame_hdr部分。 例如,这是二进制程序Perlbench的部分信息。 readelf -S perlbench There are 28 section headers, starting at offset 0x102e48: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 08048154 000154 000013 00 A 0 0 1 [ 2] .note.ABI-tag […]

clflush通过C函数使缓存行无效

我试图使用clflush手动驱逐缓存行,以确定缓存和行大小。 我没有找到关于如何使用该指令的任何指南。 我所看到的,是一些使用更高级别function的代码。 有一个内核函数void clflush_cache_range(void *vaddr, unsigned int size) ,但我仍然不知道在我的代码中包含什么以及如何使用它。 我不知道该function的size是多少。 更重要的是,我怎样才能确定该行被驱逐以validation我的代码的正确性? 更新: 这是我想要做的初始代码。 #include #include #include #include int main() { int array[ 100 ]; /* will bring array in the cache */ for ( int i = 0; i < 100; i++ ) array[ i ] = i; /* FLUSH A LINE */ /* […]

函数调用循环比空循环快

我将一些程序集与一些c链接起来测试函数调用的成本,使用以下程序集和c源代码(分别使用fasm和gcc) 部件: format ELF public no_call as “_no_call” public normal_call as “_normal_call” section ‘.text’ executable iter equ 100000000 no_call: mov ecx, iter @@: push ecx pop ecx dec ecx cmp ecx, 0 jne @b ret normal_function: ret normal_call: mov ecx, iter @@: push ecx call normal_function pop ecx dec ecx cmp ecx, 0 jne @b […]

如何在没有编译器浪费指令归零上层元素的情况下将标量合并到向量中? 英特尔内在函数的设计限制?

我没有特定的用例; 我问这是否真的是英特尔内在函数中的设计缺陷/限制,或者我是否只是遗漏了某些内容。 如果你想将标量浮点数与现有向量相结合,那么使用英特尔内在函数时,如果没有高元素归零或将标量广播到向量中,似乎没有办法实现。 我没有研究过GNU C本机向量扩展和相关的内置函数。 如果额外的内在优化,这不会太糟糕,但它不与gcc(5.4或6.2)。 使用pmovzx或insertps作为载荷也没有好的方法,因为它们的内在函数只采用向量args的相关原因。 (并且gcc不会将标量 – >向量加载到asm指令中。) __m128 replace_lower_two_elements(__m128 v, float x) { __m128 xv = _mm_set_ss(x); // WANTED: something else for this step, some compilers actually compile this to a separate insn return _mm_shuffle_ps(v, xv, 0); // lower 2 elements are both x, and the garbage is gone } gcc 5.3 […]

使用GNU C内联汇编在VGA内存中绘制字符

我正在学习用DOS和内联汇编在DOS下进行一些低级VGA编程。 现在我正在尝试创建一个在屏幕上打印出一个角色的function。 这是我的代码: //This is the characters BITMAPS uint8_t characters[464] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x50, 0x50,0x00,0x00,0x00,0x00,0x00,0x50,0xf8,0x50,0x50,0xf8,0x50,0x00,0x20,0xf8,0xa0, 0xf8,0x28,0xf8,0x00,0xc8,0xd0,0x20,0x20,0x58,0x98,0x00,0x40,0xa0,0x40,0xa8,0x90, 0x68,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x40,0x40,0x40,0x20,0x00, 0x20,0x10,0x10,0x10,0x10,0x20,0x00,0x50,0x20,0xf8,0x20,0x50,0x00,0x00,0x20,0x20, 0xf8,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x60,0x20,0x40,0x00,0x00,0x00,0xf8,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x08,0x10,0x20,0x40,0x80, 0x00,0x70,0x88,0x98,0xa8,0xc8,0x70,0x00,0x20,0x60,0x20,0x20,0x20,0x70,0x00,0x70, 0x88,0x08,0x70,0x80,0xf8,0x00,0xf8,0x10,0x30,0x08,0x88,0x70,0x00,0x20,0x40,0x90, 0x90,0xf8,0x10,0x00,0xf8,0x80,0xf0,0x08,0x88,0x70,0x00,0x70,0x80,0xf0,0x88,0x88, 0x70,0x00,0xf8,0x08,0x10,0x20,0x20,0x20,0x00,0x70,0x88,0x70,0x88,0x88,0x70,0x00, 0x70,0x88,0x88,0x78,0x08,0x70,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x30,0x30, 0x00,0x30,0x10,0x20,0x00,0x00,0x10,0x20,0x40,0x20,0x10,0x00,0x00,0xf8,0x00,0xf8, 0x00,0x00,0x00,0x00,0x20,0x10,0x08,0x10,0x20,0x00,0x70,0x88,0x10,0x20,0x00,0x20, 0x00,0x70,0x90,0xa8,0xb8,0x80,0x70,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x00,0xf0, 0x88,0xf0,0x88,0x88,0xf0,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x00,0xe0,0x90,0x88, 0x88,0x90,0xe0,0x00,0xf8,0x80,0xf0,0x80,0x80,0xf8,0x00,0xf8,0x80,0xf0,0x80,0x80, 0x80,0x00,0x70,0x88,0x80,0x98,0x88,0x70,0x00,0x88,0x88,0xf8,0x88,0x88,0x88,0x00, 0x70,0x20,0x20,0x20,0x20,0x70,0x00,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x90,0xa0, 0xc0,0xa0,0x90,0x88,0x00,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x88,0xd8,0xa8,0x88, 0x88,0x88,0x00,0x88,0xc8,0xa8,0x98,0x88,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x70, 0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x00,0x70,0x88,0x88,0xa8,0x98,0x70,0x00,0xf0, 0x88,0x88,0xf0,0x90,0x88,0x00,0x70,0x80,0x70,0x08,0x88,0x70,0x00,0xf8,0x20,0x20, 0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x88,0x88,0x88,0x88,0x50, 0x20,0x00,0x88,0x88,0x88,0xa8,0xa8,0x50,0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00, 0x88,0x50,0x20,0x20,0x20,0x20,0x00,0xf8,0x10,0x20,0x40,0x80,0xf8,0x00,0x60,0x40, 0x40,0x40,0x40,0x60,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x30,0x10,0x10,0x10, 0x10,0x30,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8, 0x00,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8}; /************************************************************************** * put_char * * Print char * **************************************************************************/ void put_char(int x ,int y,int […]