我试图通过使用物理时钟来测量c ++中某些命令的执行时间,但是我遇到了一个问题,即从计算机上的物理时钟读取测量值的过程可能需要很长时间.这是代码:
#include <string>
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <time.h>
int main()
{
int64_t mtime, mtime2, m_TSsum, m_TSssum, m_TSnum, m_TSmax;
struct timespec t0;
struct timespec t1;
int i,j;
for(j=0;j<10;j++){
m_TSnum=0;m_TSsum=0; m_TSssum=0; m_TSmax=0;
for( i=0; i<10000000; i++) {
clock_gettime(CLOCK_REALTIME,&t0);
clock_gettime(CLOCK_REALTIME,&t1);
mtime = (t0.tv_sec * 1000000000LL + t0.tv_nsec);
mtime2= (t1.tv_sec * 1000000000LL + t1.tv_nsec);
m_TSsum += (mtime2-mtime);
m_TSssum += (mtime2-mtime)*(mtime2-mtime);
if( (mtime2-mtime)> m_TSmax ) { m_TSmax = (mtime2-mtime);}
m_TSnum++;
}
std::cout << "Average "<< (double)(m_TSsum)/m_TSnum
<< " +/- " << …Run Code Online (Sandbox Code Playgroud) mov 0x0ff, 10
sfence
mov 0x0ff, 12
sfence
Run Code Online (Sandbox Code Playgroud)
它可以由x86-CPU执行:
mov 0x0ff, 12
sfence
Run Code Online (Sandbox Code Playgroud)
?
我已经读过一些CPU重新排序指令,但这对于单线程程序来说不是问题(指令仍会在单线程程序中重新排序,但看起来好像指令是按顺序执行的),这只是一个问题用于多线程程序.
为了解决指令重新排序的问题,我们可以在代码中的适当位置插入内存屏障.
但x86 CPU是否重新排序指令?如果没有,那么就没有必要使用内存屏障了吧?
x86 assembly multithreading cpu-architecture memory-barriers
在最近的Intel和AMD CPU上,执行的预取指令是否仍然可以退出,但是请求的行还没有到达指定的缓存级别?
也就是说,预取"阻塞"的退出是因为它似乎是负载,还是非阻塞?
有没有办法从Linux中的信号处理程序获取当前线程ID?该getpid()方法可以满足我的需求,但目前尚不清楚它是否是异步安全的.man 7 signal提供了一个异步安全的POSIX方法列表,但这并没有告诉我们非POSIX方法,例如getpid().据推测,Linux添加的许多非POSIX方法中的一些是异步安全的,但我找不到列表.
还有这个答案声称所有直接(非多路复用)系统调用都是异步安全的,但没有提供任何证据.
目标是构建某种异步安全的线程本地存储,因为在一般情况下__thread 是不安全的.
它不一定是"Linux线程ID" - 任何一致的线程ID都可以.例如,pthread_self这将是伟大的,但没有任何声称是异步安全的.如果我们在glibc Linux中检查该方法的实现,它会延迟到THREAD_SELF宏,它看起来像:
# define THREAD_SELF \
({ struct pthread *__self; \
asm ("movl %%gs:%c1,%0" : "=r" (__self) \
: "i" (offsetof (struct pthread, header.self))); \
__self;})
Run Code Online (Sandbox Code Playgroud)
这似乎是,这应该是异步安全的,如果有问题的线程用于填充制度下创建gs语域(也许是在Linux中的所有线程,我不知道).仍然看着那个标题让我非常害怕......
在我的 MSVC 2015 项目中,我有一个函数,int foo(int, int)它在 .asm 文件中实现。当我extern "C"在同一个项目的 .cpp 文件中声明这个函数时,Intellisense 抱怨Function definition for 'foo' not found.:
我不知道为什么 Intellisense 认为它通常可以找到 extern 函数的定义 - 其中很多将在 dll、静态库或其他二进制格式中声明,而在编译时没有可用的源,更不用说我的 .asm (编译为 .obj 作为项目构建的一部分)文件案例。
我应该提到该项目构建良好并且foo()被调用没有问题。
Intellisense在这方面的问题是什么,如何解决?
是否可以al, ah, bl, bh, r8b在x86-64中的索引寻址模式下使用8位寄存器()?例如:
mov ecx, [rsi + bl]
mov edx, [rdx + dh * 2]
Run Code Online (Sandbox Code Playgroud)
特别是,这将允许您使用寄存器的底部8位作为0-255偏移量,这对某些内核可能很有用.
我倾注了英特尔的手册,他们并没有明确说明这一点,但他们给出的所有例子都只有32位或64位的基址和索引寄存器.在32位代码中,我只看到16位或32位寄存器.看一下mod-r/m和SIB字节编码的细节似乎也指向"不",但这足够复杂,有足够的角落情况,我不确定我是否正确.
我最感兴趣的是x86-64行为,但当然如果它只能在32位模式下我想知道.
作为一个太小而且与之相关的附加问题,可以使用16位寄存器作为基数还是索引?例如,mov rax, [rbx + cx].我的调查指出了与上面基本相同的答案:可能不是.
是否可以使用最近的Intel x86芯片上的性能计数器来衡量成功的存储转发操作的数量?
我看到ld_blocks.store_forward哪些措施无法存储转发的事件,但我很清楚是否可以测量成功案例.
我想在C程序和要由nasm或yasm编译的程序集文件中包括很多魔术数字。
在纯C语言中,文件看起来像一系列定义,例如:
#define BLESS 55378008
#define ANSWER 42
...
Run Code Online (Sandbox Code Playgroud)
在nasm或yasm中,相同的include可以实现为:
%define BLESS 55378008
%define ANSWER 42
...
Run Code Online (Sandbox Code Playgroud)
唯一的不同是C和nasm 的define:前面的主角。#%
有什么办法可以编写一个polygot include,它可以让我将它同时包含在C和nasm中,并且只列出一次常量?
是的,我知道我可以使用sed或其他方法从另一个文件生成一个文件。
考虑以下returnsNull函数并使用泛型类型调用它:
public static <T> List<T> returnNull(Class<? extends T> clazz) {
return null;
}
public static void main( String[] args )
{
List<AtomicReference<?>> l = returnNull(AtomicReference.class);
}
Run Code Online (Sandbox Code Playgroud)
Eclipse编译器在设置为Java 8时接受它,但javac在Java 8中拒绝它:
incompatible types: cannot infer type-variable(s) T
(argument mismatch; java.lang.Class<java.util.concurrent.atomic.AtomicReference> cannot be converted to java.lang.Class<? extends java.util.concurrent.atomic.AtomicReference<?>>)
Run Code Online (Sandbox Code Playgroud)
底层差异似乎是给定两个参数化类型,P1<T>并且P2<T>Eclipse允许从使用原始内部类型参数化的外部类型转换为P1<P2>使用无界通配符的内部类型的下限参数化的外部类型P1<? extends P2<?>>.javac没有.
这不仅仅是一个理论上的思考:如果这个代码被接受,它将解决我的泛型过滤问题.
谁是对的?