我有一个问题需要了解是否有更好的解决方案。我编写了以下代码,将一些变量从编写器线程传递到读取器线程。这些线程固定到共享相同 L2 缓存的不同 CPU(禁用超线程)。
writer_thread.h
struct a_few_vars {
uint32_t x1;
uint32_t x2;
uint64_t x3;
uint64_t x4;
} __attribute__((aligned(64)));
volatile uint32_t head;
struct a_few_vars xxx[UINT16_MAX] __attribute__((aligned(64)));
Run Code Online (Sandbox Code Playgroud)
reader_thread.h
uint32_t tail;
struct a_few_vars *p_xxx;
Run Code Online (Sandbox Code Playgroud)
写入线程增加头变量,读取线程检查头变量和尾变量是否相等。如果它们不相等,则按如下方式读取新数据
while (true) {
if (tail != head) {
.. process xxx[head] ..
.. update tail ..
}
}
Run Code Online (Sandbox Code Playgroud)
性能是迄今为止最重要的问题。我使用的是 Intel Xeon 处理器,读取器线程每次都会从内存中获取 head 值和 xxx[head] 数据。我使用对齐数组来实现无锁
就我而言,是否有任何方法可以尽快将变量刷新到读取器CPU缓存中。我可以从写入器 CPU 触发读取器 CPU 的预取吗?如果存在的话,我可以使用 __asm__ 来使用特殊的英特尔指令。总之,在固定到不同 CPU 的线程之间传递结构中的变量的最快方法是什么?
提前致谢
我想要实现什么
我尝试建立一个工具链来编译适用于英特尔 FPGA 的 OpenCL 应用程序。因此,在构建基于 C++ 的主机应用程序时,我需要为 OpenCL 内核调用英特尔 OpenCL 离线编译器。
仅当编辑了 cl 源文件或生成的二进制文件丢失时才应执行此步骤。我的方法是添加一个自定义命令来调用 CL 编译器并创建一个取决于该命令生成的输出的自定义目标。离线 Open CL 编译器被调用aoc
,并且由于系统上可能存在多个 SDK 版本,我使用存储在aocExecutable
. 这是我的 CMakeLists.txt 的相关部分
set (CLKernelName "vector_add")
set (CLKernelSourceFile "${PROJECT_SOURCE_DIR}/${CLKernelName}.cl")
set (CLKernelBinary "${PROJECT_BINARY_DIR}/${CLKernelName}.aocx")
add_executable (HostApplication main.cpp)
# ------ a lot of unneccessary details here ------
add_custom_command (OUTPUT "${CLKernelBinary}"
COMMAND "${aocExecutable} -march=emulator ${CLKernelSourceFile} -o ${CLKernelBinary}"
DEPENDS "${CLKernelSourceFile}"
)
add_custom_target (CompileCLSources DEPENDS "${CLKernelBinary}")
add_dependencies (HostApplication CompileCLSources)
Run Code Online (Sandbox Code Playgroud)
什么不起作用 在 Linux 下的 CLion IDE 中运行此命令会导致以下错误:
/bin/sh: 1: /home/me/SDKsAndFrameworks/intelFPGA/18.1/hld/bin/aoc -march=emulator …
Run Code Online (Sandbox Code Playgroud) 我一直在阅读有关哪个头文件更适合访问英特尔内在函数的意见:x86intrin.h
或immintrin.h
。
两者似乎都达到了相同的结果,但我确信在代码可移植性方面一定存在一些细微的差异。也许其中一个比另一个更常见或更完整?
我找不到对其中任何一个的解释。如果有人知道为什么有两个文件,以及它们有什么区别,这将是一个受欢迎的答案。
说到可移植性,对于较旧的编译器(例如gcc
< v4.4.0),事情当然会变得更加复杂,而且两者都不可用。必须考虑包含另一个内在标头(可能emmintrin.h
用于 SSE 支持)。
首先:这个问题是关于IA-32(x86)架构的。
我有一个关于旧版(非 PSE、非 PAE)寻呼的问题。在传统分页中,我们有一个包含 1024 个条目的页目录,每个条目都指向一个页表。每个页表包含 1024 个条目(这些是页),每个条目都指向一个 4096 字节对齐的物理地址。
同时,每个页目录项和页表项都保存一些标志,并且它们都有一个“U”标志(位#2):如果设置了该标志,则该页可以由用户(ring3)和用户(ring3)访问。主管(ring0);但是,如果未设置此标志,则只有管理程序 (ring0) 可以访问它。该标志通常称为“用户/管理员位”。
问题:如果我想让ring0和ring3页都在同一个页表中,该怎么办?我可以为页表中的条目设置适当的权限,但是相应的页目录条目应该指定什么权限呢?
例如:我设置了第一个页表(虚拟地址范围:0x00000000 - 0x003FFFFF)来映射物理地址范围0x00000000 - 0x003FFFFF(这涵盖了4兆字节)。第一个兆字节 (0x00000000 - 0x000FFFFF) 只能由管理员 (ring0) 访问,因此,“用户/管理员位”被清除。以下 3 MB (0x00100000 - 0x003FFFFF) 应可由用户 (ring3) 和管理员 (ring0) 访问,因此,设置“用户/管理员位”。
该页表由第一个页目录项指向。但是该页目录条目的“用户/管理员位”应该被清除(仅管理员)还是设置(用户和管理员)?有什么不同?
假设我想修改现有指令的实现。例如,假设我想更改在获取和解码后执行“mov”指令时由处理器执行的微代码。我该怎么做呢?
另外,假设我想向 ISA 添加一条新指令。例如,假设有一个当前未使用的操作码,我希望我的处理器能够在获取它后对其进行解码和执行。我该怎么做呢?
说实话,我什至不知道从哪里开始,这就是我询问堆栈溢出的原因。我没有任何编写微代码的经验,我只从计算机架构课上知道这个术语。我知道查找 x86 指令列表非常容易,但我不知道在哪里查找微指令列表。我什至不知道英特尔是否公开了他们的微代码列表。我不知道需要使用什么程序将这些新的微程序加载到 CPU 内的适当内存中。我认为引导加载程序可能参与其中,但我对此可能完全错误。如果我拥有我的 CPU,我认为我可以合法地修改其微代码并对其指令进行逆向工程,但通过现有文档(而不是通过逆向工程)更容易理解我的 CPU 的工作原理以及如何更改其微代码。
我知道有一些较小的硬件供应商生产开源 ISA,所以如果我想尝试一下,从这些供应商之一购买 CPU 可能会更好?但我不知道替代供应商的哪种 CPU 最适合这种情况。但实际上,我认为对于我想做的事情来说没有必要购买新的 CPU,因为如果必须的话,我可以使用现有的 CPU 在虚拟机中运行开源 ISA(我是从软件角度而不是硬件角度对微指令和微程序感兴趣)。
我观察到,与Intel CPU相比,我在AMD处理器上执行java应用程序的速度要快得多.
例如,我的JBoss在3 GHz AMD处理器上启动大约30秒,在具有相同光盘,RAM和操作系统的3 GHz Intel处理器上需要大约60秒?
还有其他人做过这个观察吗?为什么会这样?
我知道Linux提供int 0x80
了陷入系统调用但是还有其他什么,它们的用途是什么?
有谁知道如何将英特尔媒体SDK(版本:Media SDK 2010)H.264视频帧解码输出NV12格式转换为RGB888(RGB24)位转换?
基本上Media SDK解码器输出将采用NV12格式,并且渲染需要RGB24位格式,因此如果任何转换代码可用于转换NV12 - > RGB24将对我们有很大帮助.
我想在linux上编译OPENMP fortran代码.我有大约230个子程序.我用来编译代码的代码如下:1)首先,我使用以下命令编译每个子例程
ifort -c -override-limits -openmp *.for
Run Code Online (Sandbox Code Playgroud)
然后所有子程序现在都有一个单独的目标文件.
2)然后我尝试通过以下命令将目标文件编译为可执行文件
ifort *.o -o myprogram
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
WINDWAVE.F90:(.text+0x1c9d): undefined reference to `__kmpc_global_thread_num'
WINDWAVE.F90:(.text+0x1cb0): undefined reference to `__kmpc_ok_to_fork'
WINDWAVE.F90:(.text+0x1eea): undefined reference to `__kmpc_fork_call'
WINDWAVE.F90:(.text+0x1f09): undefined reference to `__kmpc_serialized_parallel'
WINDWAVE.F90:(.text+0x214b): undefined reference to `__kmpc_end_serialized_parallel'
WINDWAVE.F90:(.text+0x2427): undefined reference to `__kmpc_for_static_init_4'
WINDWAVE.F90:(.text+0x29c7): undefined reference to `__kmpc_for_static_fini'
WINDWAVE.F90:(.text+0x29da): undefined reference to `__kmpc_barrier'
WINDWAVE.F90:(.text+0x2a50): undefined reference to `__kmpc_for_static_init_4'
WINDWAVE.F90:(.text+0x3773): undefined reference to `__kmpc_for_static_fini'
WINDWAVE.F90:(.text+0x3786): undefined reference to `__kmpc_barrier'
WINDWAVE.F90:(.text+0x37fc): undefined reference to `__kmpc_for_static_init_4'
WINDWAVE.F90:(.text+0x4a58): undefined reference to `__kmpc_for_static_fini'
WINDWAVE.F90:(.text+0x4a6b): …
Run Code Online (Sandbox Code Playgroud) 我在Barry B. Brey的"THE INTEL MICROPROCESSORS"一书中找到了这个.这是真的吗?但为什么?我知道在实际的8086微处理器的实模式中,没有32位寄存器.那么现在应该对32位寄存器施加同样的限制吗?
intel ×10
x86 ×5
c ×2
assembly ×1
c++ ×1
clion ×1
cmake ×1
codec ×1
color-codes ×1
cpu-cache ×1
fortran ×1
gcc ×1
header ×1
int ×1
intel-fpga ×1
intrinsics ×1
java ×1
linux ×1
memory ×1
microcoding ×1
openmp ×1
osdev ×1
paging ×1
performance ×1
real-mode ×1
system-calls ×1
winapi ×1