|
|
1
1
问题中原始版本的主要问题是,它需要使用寄存器间接寻址,并为锁双字取一个引用(或指针参数),而不是按值参数。 这是VisualC++的工作解决方案。 编辑: 我已经和作者离线工作,我们已经验证了这个答案中的代码在他的测试工具中是否正确工作。 但是,如果您使用的是Windows,那么应该使用联锁API(即InterlockedExchange)。
编辑:如CAF所述,
我还添加了一个更快的版本,在尝试执行
|
|
|
2
6
如果你是为Windows写的,你应该认真考虑使用 critical section 对象。关键部分API函数经过了优化,这样它们就不会转换到内核模式,除非它们确实需要这样做,所以正常情况下无争用的开销非常小。 旋转锁最大的问题是,如果您在一个CPU系统上,并且正在等待锁,那么您正在使用所有可以使用的周期,并且持有锁的任何东西在您的时间片打开并且内核抢占线程之前都无法运行。 使用关键部分将比尝试滚动您自己的用户模式自旋锁更成功。 |
|
|
3
4
就您的实际问题而言,这非常简单:只需更改函数头即可使用
和
但是,请注意,还有一些其他问题即将出现:
实际上,如果您担心锁定,这意味着您正在使用线程,这可能意味着您已经在使用平台特定的线程API。因此,使用本机同步原语,并在切换到Linux时切换到pthreads版本。 |
|
|
4
3
显然,您正在使用C++代码中的内联汇编块编译MSVC。 一般来说,你应该 compiler intrinsics 因为内联程序集没有未来:在为x64编译时,它不再支持我的MS编译器。 如果需要在程序集中对函数进行微调,则必须在单独的文件中实现它们。 |
|
|
5
1
您应该使用这样的工具:
|
|
|
6
0
查看编译器文档,了解如何打印生成的函数汇编语言。 打印此函数的汇编语言:
这可能不起作用,因为编译器可以优化函数并删除所有代码。您应该更改上面的函数以将指针传递给
|
|
|
7
-1
我已经提供了一个工作版本,它回答了原始海报的问题,包括如何在ASM中传递参数以及如何使其锁正常工作。 许多其他答案质疑使用asm的明智性,并提到应该使用intrinsics或c os调用。下面的工作也是我的ASM答案的C++版本。其中有一小段asm,仅当您的平台不支持interlockedexchange()时才需要使用。
|