小编Jam*_*mes的帖子

哪个内联汇编代码对于rdtscp是正确的?

免责声明:单词无法描述我厌恶AT&T风格的语法

我有一个问题,我希望是由寄存器clobbering引起的.如果没有,我有一个更大的问题.

我使用的第一个版本是

static unsigned long long rdtscp(void)
{
    unsigned int hi, lo;
    __asm__ __volatile__("rdtscp" : "=a"(lo), "=d"(hi));
    return (unsigned long long)lo | ((unsigned long long)hi << 32);
}
Run Code Online (Sandbox Code Playgroud)

我注意到这个版本中没有'破坏'的东西.这是否是一个我不知道的问题...我想这取决于编译器是否内联函数.使用此版本会导致我无法始终重现的问题.

我发现的下一个版本是

static unsigned long long rdtscp(void)
{
    unsigned long long tsc;
    __asm__ __volatile__(
        "rdtscp;"
        "shl $32, %%rdx;"
        "or %%rdx, %%rax"
        : "=a"(tsc)
        :
        : "%rcx", "%rdx");

    return tsc;
}
Run Code Online (Sandbox Code Playgroud)

这是令人安心的不可读和官方的看,但就像我说我的问题并不总是可重复的所以我只是试图排除我的问题的一个可能的原因.

认为第一个版本存在问题的原因是它覆盖了以前持有函数参数的寄存器.

什么是正确的...版本1,或版本2,或两者兼而有之?

assembly gcc x86-64 inline-assembly

14
推荐指数
1
解决办法
8350
查看次数

sig_atomic_t和std :: atomic <>可以互换吗?

根据标题.我可以std::atomic<>在信号处理程序中使用还是sig_atomic_t提供其他编译器功能?

c++ signals atomic

13
推荐指数
1
解决办法
1346
查看次数

为什么std :: to_string没有std :: string重载

标题说明了一切.为什么他们选择没有

namespace std
{
    std::string to_string(const std::string&)
}
Run Code Online (Sandbox Code Playgroud)

超载?

我有一个程序,可以按行索引或行名查询一些数据; 非常适合模板.直到我尝试构造一个错误消息,如果正在访问的行丢失:

template <typename T>
int read(T nameOrIndex)
{
    if (!present(nameOrIndex))
    {
        // This does not compile if T is std::string.
        throw std::invalid_argument("Missing row: " + std::to_string(nameOrIndex));
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以将自己的重载添加到std命名空间,但这并不理想.

c++ c++11

12
推荐指数
1
解决办法
1205
查看次数

何时用单例替换全局std :: unique_ptr

一位同事坚持将Meyer的Singleton用于所有全局指针变量,因为"不能保证全局构建unique_ptr不会抛出".所以代替:

#include <memory>

std::unique_ptr<Foo> ptr(nullptr); // Apparently this isn't safe.

int main(/*blah*/)
{
    ptr.reset(new Foo());
}
Run Code Online (Sandbox Code Playgroud)

我们现在有

unique_ptr<Foo> singleton
{ 
    try 
    { 
        static unique_ptr<Foo> ptr(); 
        return ptr; 
    } 
    catch (...) 
    { 
        std::cerr << "Failed to create single instance\n"; 
        exit(1); 
    } 
    return unique_ptr<Type>(); 
}

int main()
{
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这似乎是寻找问题的解决方案.他有意见吗?

c++

10
推荐指数
1
解决办法
4596
查看次数

使用带有纯虚函数的C++ 11线程

我有代码,其中要在单独的线程中执行的对象派生自具有纯虚Run函数的基类.我无法获得以下(简化的测试代码)来运行新线程.

#include <iostream>
#include <thread>
#include <functional>

class Base {
public:
    virtual void Run() = 0;
    void operator()() { Run(); }
};

class Derived : public Base {
public:
    void Run() { std::cout << "Hello" << std::endl; }
};

void ThreadTest(Base& aBase) {
    std::thread t(std::ref(aBase));
    t.join();
}

int main(/*blah*/) {
    Base* b = new Derived();
    ThreadTest(*b);
}
Run Code Online (Sandbox Code Playgroud)

代码编译很好(这是战斗的一半),但"Hello"永远不会打印.如果我做错了什么我会在某个时候发现运行时错误.我正在使用gcc.

编辑:上面的代码无法在VS2012上编译,具有: error C2064: term does not evaluate to a function taking 0 arguments

你需要使用lambda代替std::ref,即

void ThreadTest(Base& aBase)
{ …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading c++11 visual-studio-2012

8
推荐指数
1
解决办法
1880
查看次数

AtomicLong.lazySet的C++端口

我正在尝试将一些Java代码移植到Windows C++,并对如何实现感到困惑AtomicLong.lazySet().我能找到的唯一信息是关于它的作用,而不是如何实现它,可用的源代码最终存在于Sun(sun.misc.Unsafe.class)拥有的私有本机库中.

我目前只是将一个成员变量设置为传递的参数,但我不确定它是否正确.

class AtomicLong
{
public:
    inline void LazySet(__int64 aValue)
    {
        // TODO: Is this correct?
        iValue = aValue;
    }

    inline void Set(__int64 aValue)
    {
        ::InterlockedExchange64(&iValue, aValue);
    }

private:
    __declspec(align(64)) volatile __int64 iValue;
};
Run Code Online (Sandbox Code Playgroud)

我不能用boost.

编辑:我正在编译为x64,但32位代码的解决方案可能会对其他人有所帮助.

我无法访问C++ 11.

c++ java atomic

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

有条件地包括源文件

在我的根CMakeLists.txt中

add_definition(-DMY_MACRO)
Run Code Online (Sandbox Code Playgroud)

然后在一个子CMakeLists.txt我想做的事情

add_library(mylib, STATIC
    file1
#ifdef MY_MACRO
    file2
#endif
)
Run Code Online (Sandbox Code Playgroud)

我试过类似的东西

IF( DEFINED MY_MACRO )
SET(FILE2 "file2")
ELSE( DEFINED MY_MACRO )
SET(FILE2 "")
END_IF( DEFINED MY_MACRO )

add_library(mylib static
    file1
    ${FILE2}
)
Run Code Online (Sandbox Code Playgroud)

但没有快乐.

cmake

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

堆栈展开真的需要锁吗?

我一直在用mutrace分析我的代码并且有以下有趣/令人担忧的结果:

Mutex #1260690 (0x0x7f87bc8eea40) first referenced by:
    /usr/lib/mutrace/libmutrace.so(pthread_mutex_lock+0x49) [0x7f87be0b76b9]
    /lib/x86_64-linux-gnu/libgcc_s.so.1(_Unwind_Find_FDE+0x26) [0x7f87bc6eb0e6]

mutrace: Showing 10 most contended mutexes:

Mutex #   Locked  Changed    Cont. tot.Time[ms] avg.Time[ms] max.Time[ms]  Flags
1260690 19066789  1509831   109753     3600.883        0.000        0.226 M-.--.
Run Code Online (Sandbox Code Playgroud)

_Unwind_Find_FDE似乎要处理堆栈展开.

我的应用程序是高度多线程的,具有非常严格的延迟要求,所以我想尽可能简单地消除它.是否有任何编译器或环境设置我可以用来摆脱这个函数调用,而不重写我的代码?我们确实对流控制的一部分使用异常(可能是不明智的)但是修复它是一个很大的重构工作.

g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Run Code Online (Sandbox Code Playgroud)

c++ gcc

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

为什么'这个'不易变?

在最后几天调试多线程,其中一个线程正在删除另一个仍在使用的对象,我意识到如果我可以使'this'易变,问题会更容易和更快地诊断.它会将系统(Symbian OS)上的故障转储更改为更具信息性的内容.

那么,有什么理由不能或不应该是这样吗?

编辑:所以真的没有安全的方法来防止或检查这种情况.如果说访问过时类指针的一个解决方案是拥有一个保存指针的全局变量,并且调用的任何函数应该是使用全局变量替换'this'的静态函数,这是否正确?

static TAny* gGlobalPointer = NULL;

#define Harness static_cast<CSomeClass*>(gGlobalPointer);

class CSomeClass : public CBase
    {
public:
    static void DoSomething();

private:
    int iMember;
    };


void CSomeClass::DoSomething()
    {
    if (!Harness)
        {
        return;
        }

    Harness->iMember = 0;
    }
Run Code Online (Sandbox Code Playgroud)

因此,如果删除另一个线程并将全局指针置空,则会立即捕获它.

我认为这个问题的一个问题是,如果编译器缓存了Harness的值而不是每次使用时都检查它.

c++ symbian

5
推荐指数
1
解决办法
451
查看次数

std :: atomic <int*> :: load应该进行比较和交换循环吗?

简介:我曾预料到,只要加载的值很少改变std::atomic<int*>::load,std::memory_order_relaxed就会接近直接加载指针的性能.我看到原子负载的性能远远低于Visual Studio C++ 2012上的正常负载,因此我决定进行调查.事实证明原子负载是作为比较和交换循环实现的,我怀疑它不是最快的实现.

问题:是否有某些原因std::atomic<int*>::load需要进行比较和交换循环?

背景:我相信MSVC++ 2012正在基于此测试程序对指针的原子加载进行比较和交换循环:

#include <atomic>
#include <iostream>

template<class T>
__declspec(noinline) T loadRelaxed(const std::atomic<T>& t) {
  return t.load(std::memory_order_relaxed);
}

int main() {
  int i = 42;
  char c = 42;
  std::atomic<int*> ptr(&i);
  std::atomic<int> integer;
  std::atomic<char> character;
  std::cout
    << *loadRelaxed(ptr) << ' '
    << loadRelaxed(integer) << ' '
    << loadRelaxed(character) << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用一个__declspec(noinline)函数来隔离与原子负载相关的汇编指令.我做了一个新的MSVC++ 2012项目,添加了一个x64平台,选择了发布配置,在调试器中运行程序并查看了反汇编.事实证明,两者std::atomic<char>std::atomic<int>参数最终会给出相同的调用loadRelaxed<int>- 这必须是优化器所做的事情.这是被调用的两个loadRelaxed实例的反汇编:

loadRelaxed<int …

c++ atomic visual-c++ compare-and-swap visual-studio-2012

5
推荐指数
1
解决办法
1437
查看次数