免责声明:单词无法描述我厌恶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,或两者兼而有之?
根据标题.我可以std::atomic<>在信号处理程序中使用还是sig_atomic_t提供其他编译器功能?
标题说明了一切.为什么他们选择没有
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命名空间,但这并不理想.
一位同事坚持将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)
对我来说,这似乎是寻找问题的解决方案.他有意见吗?
我有代码,其中要在单独的线程中执行的对象派生自具有纯虚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) 我正在尝试将一些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.
在我的根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)
但没有快乐.
我一直在用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) 在最后几天调试多线程,其中一个线程正在删除另一个仍在使用的对象,我意识到如果我可以使'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的值而不是每次使用时都检查它.
简介:我曾预料到,只要加载的值很少改变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 …