小编Bee*_*ope的帖子

在 futex 之前,Linux 中的线程/进程是如何停放和唤醒的?

在 Linux 中存在系统调用之前futex,线程库使用哪些底层系统调用来pthreads阻塞/休眠线程并随后从用户空间唤醒这些线程?

例如,如果一个线程尝试获取互斥锁,用户态实现将阻止该线程(可能在很短的旋转间隔之后),但我找不到用于此目的的系统调用(除了相对较新的创建的系统调用之外futex) )。

linux multithreading futex

6
推荐指数
1
解决办法
2520
查看次数

membarrier手册页中的示例在x86中是无意义的吗?

也许这只是我,但man 2页面中的例子membarrier似乎毫无意义.

基本上,membarrier()是一个异步内存屏障,给定两个协调的代码段(让我们调用然后快速路径慢速路径)允许您将屏障的所有硬件成本移动到慢速路径,并且只保留快速路径编译屏障1.有几种不同的方法可以完成这种membarrier行为,例如向每个涉及的处理器发送IPI或等待每个处理器上运行的代码被取消调度 - 但具体的实现细节在这里并不重要.

现在,这是手册页中给出的示例转换:

原始代码

static volatile int a, b;

static void
fast_path(void)
{
   int read_a, read_b;

   read_b = b;
   asm volatile ("mfence" : : : "memory");
   read_a = a;

   /* read_b == 1 implies read_a == 1. */

   if (read_b == 1 && read_a == 0)
       abort();
}

static void
slow_path(void)
{
   a = 1;
   asm volatile …
Run Code Online (Sandbox Code Playgroud)

linux x86 memory-model memory-barriers

6
推荐指数
2
解决办法
268
查看次数

是否可以通过基准比较ARM和x86的性能?

从最新消息来看,新的苹果处理器A11 Bionic在Geekbench基准测试中比移动英特尔酷睿i7得分更高。

据我了解,该基准测试中有很多不同的测试。这些测试模拟了不同的负载,包括日常使用中可能发生的负载。

有人指出,这些结果无法与x86结果进行比较。他们说x86能够执行“更复杂的任务”。例如,他们领导Photoshop,视频转换,科学计算。我同意ARM的软件通常只是台式机软件的“轻量级”版本。但是在我看来,这种限制是由移动操作系统的格式(移动中完成工作,没有鼠标等)引起的,而不是由ARM的性能引起的。

作为相反的示例,让我们看一下Safari。浏览器是一个复杂的程序。Safari在iPad上的工作原理与Mac一样。此外,如果我们采用Sunspider(JS基准测试)的结果,事实证明iPad上的Safari得分更高。

我认为在日常任务(Web,Office,音乐/电影)中,ARM(A10X,A11)和x86(双核移动英特尔i7)的性能是可比的和相等的。

ARM真的有远远落后于x86的任何类型的任务吗?如果是这样,原因是什么?是什么阻止了Apple在ARM上发布笔记本电脑?从POWER迁移到x86,他们已经做了同样的事情。这是技术限制,还是营销?

cpu benchmarking cpu-architecture

6
推荐指数
1
解决办法
9439
查看次数

有什么技巧可以使复制构造函数与类属性保持同步吗?

我相信这是一个常见问题,但有些谷歌搜索不会返回匹配项,因此请在这里询问。

所以我有以下课程:

class A {
  public:
    A(const A &rhs) { m_a = rhs.m_a; }

   private:
      int m_a;
};
Run Code Online (Sandbox Code Playgroud)

一切都很酷,直到一段时间后,可能是一年后,我添加了一个新属性m_bto class A,但我忘记更新复制构造函数。

需要进行痛苦的调试才能找到不同步的位置。

有没有办法避免这样的问题,最好是在构建时?

是的,我可以编写单元测试来覆盖该复制构造函数,但是当我忘记更新复制构造函数时,很可能我也忘记了该单元测试。

c++

6
推荐指数
1
解决办法
928
查看次数

对于设置传统帧指针的函数,是否有简单的DWARF CFI表示?

我正在编写C,C++和汇编的混合编程,我希望从代码的任何部分获得可靠的回溯.

这主要工作正常的C和C++代码,因为我可以生成调试与信息-g,这对于现代的x86编译器和平台生成DWARF调试信息,这意味着最终的二进制包括CFI(调用帧信息).此信息允许通过当前调用堆栈中的函数向后移动.它可以支持复杂的场景,例如没有基指针的函数以及rsp动态方式的变化.对于C和C++代码,我不必关心:即使对于优化的代码,编译器也会生成正确的CFI.

对于我在nasm中编写的x86汇编代码,CFI是个问题.nasm和语法兼容的竞争对手yasm对生成DWARF信息有一些有限的支持,但它主要涉及指向行映射的指令指针,并且不包括任何CFI 1(实际上,即使它集合也无法真正生成它因为程序集太低而无法明确表达调用/返回语义,所以需要.

我想为程序集生成的例程添加CFI,但我不需要CFI的完全灵活性来根据指令细化更改识别CFA rsp等等:我非常乐意设置标准框架-pointer in rbpfor each assembly function并保持整个函数的完整性.DWARF3是否通过一小段CFI信息支持这种情况,希望我能用汇编器宏生成一个?


1 yasm 的实验性"nextgen" 版本确实支持CFI指令,但该项目尚未在5年内更新.有一个未解决的问题是将此支持移回yasm的主线版本.

debugging x86 nasm backtrace dwarf

6
推荐指数
0
解决办法
209
查看次数

如何确定 gcc 支持哪些架构?

GCC 支持-march允许您指定目标架构的开关 - 允许它调整该平台的指令序列以及使用该平台上可能可用但在“默认”或基本版本上不可用的指令架构。

例如,-march=skylake将告诉编译器以 Skylake CPU 为目标,包括使用 Skylake 上可用的指令集,例如 AVX2。

如何判断-march本地版本gcc支持的值?当传递无效参数时,较新版本有助于列出有效参数,但较旧版本不会。

performance x86 gcc

6
推荐指数
1
解决办法
5549
查看次数

标准库类型和内置类型是否允许重载operator+?

当不存在这样的重载时,是否允许重载运算符,例如operator+标准库类型和内置类型的组合?

例如,在默认命名空间或用户定义的命名空间中实现以下运算符是否合法:

std::string operator+(const std::string& s, int right) { ... }
Run Code Online (Sandbox Code Playgroud)

我知道在命名空间中实现事物有各种限制std::,但我不清楚是否有任何规则违反上述规定(当然这是否是一个好主意是完全不同的事情!)。

c++ operator-overloading user-defined-types language-lawyer

6
推荐指数
1
解决办法
1077
查看次数

gcc警告未使用的静态函数,但不是静态内联:是否存在实际区别?

我的gcc版本(5.4)警告未使用的static函数,即使在使用时的头文件中-Wall也是如此.如果定义相同的功能static inline或简单,它不会抱怨inline.

例如,文件中的以下函数unused.h:

static void foo() {}
Run Code Online (Sandbox Code Playgroud)

...当包含在test.cpp文件中时如下:

#include "unused.h"
Run Code Online (Sandbox Code Playgroud)

编译时使用以下命令生成以下编译器诊断-Wall:

In file included from test.cpp:11:0:
unused.h: At global scope:
unused.h:9:13: warning: ‘void foo()’ defined but not used [-Wunused-function]
 static void foo() {}
             ^
Run Code Online (Sandbox Code Playgroud)

据我所知,通常的做法是包含具有许多实用程序功能的标头,在任何给定的源文件中只能使用少数几个.这种行为意味着我得到了我不使用的任何仅声明的函数的警告static.

作为一个实际问题,我可以简单地改变这些以static inline消除警告(或完全关闭特定警告,但我确实发现它不时有用),但似乎大型实用功能不会从中受益内联1更逻辑地声明为static2.

据我所知,在编译翻译单元时,gcc会简单地删除未使用的static函数(就像static inline),因此它们根本不会产生二进制大小或链接时间开销.

我在这里错过了什么吗?是否有充分的理由认为未使用的static功能比问题更多static inline


1是的,我知道这只是一个暗示,但gcc在很多情况下实际上都是暗示.

2或者更好,只在头文件中声明并在文件中的其他位置定义 …

c++ gcc compiler-warnings static-functions

6
推荐指数
1
解决办法
2806
查看次数

在nasm中的长nop指令

nasm是否有任何内置方法来发出给定长度的long-nop(又称多字节nops)指令?

x86 assembly nasm

6
推荐指数
1
解决办法
661
查看次数

为什么Linux性能在x86上将事件l1d.replacement用于“ L1 dcache丢失”?

在Intel x86上,Linux使用事件l1d.replacements来实现其事件。L1-dcache-load-misses事件。

此事件的定义如下:

计算L1D数据线的替换量,包括机会性替换,以及需要停顿替换的替换或需要替换块的替换。

也许天真地,我希望perf使用像这样的东西mem_load_retired.l1_miss,它支持PEBS,并且定义为:

用至少一个在L1高速缓存中未命中的uop计数退休的加载指令。(支持PEBS)

事件值通常不是非常接近,有时会发生巨大变化。例如:

$ocperf stat -e mem_inst_retired.all_loads,l1d.replacement,mem_load_retired.l1_hit,mem_load_retired.l1_miss,mem_load_retired_fb_hit head -c100M /dev/urandom > /dev/null 

 Performance counter stats for 'head -c100M /dev/urandom':

       445,662,315      mem_inst_retired_all_loads                                   
            92,968      l1d_replacement                                             
       443,864,439      mem_load_retired_l1_hit                                     
         1,694,671      mem_load_retired_l1_miss                                    
            28,080      mem_load_retired_fb_hit                                     
Run Code Online (Sandbox Code Playgroud)

与相比,“ L1未命中”的数量多于17 。相反,您也可以找到比计数器高得多的示例。mem_load_retired.l1_missl1d.replacementl1d.replacementmem_load_retired

到底在l1d.replacement测量什么,为什么要在内核中选择它,并且它比L1 d缓存未命中更好的代理mem_load_retired.l1_miss

linux x86 profiling perf intel-pmu

6
推荐指数
0
解决办法
296
查看次数