- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在 yasm
程序中使用 POSIX
线程(或简称 pthread
)库实现并行处理。
这是我程序中最重要的部分。
section .data
pThreadID1 dq 0
pThreadID2 dq 0
MAX: dq 100000000
value: dd 0
section .bss
extern pthread_create
extern pthread_join
section .text
global main
main:
;create the first thread with id = pThreadID1
mov rdi, pThreadID1
mov rsi, NULL
mov rdx, thread1
mov rcx, NULL
call pthread_create
;join the 1st thread
mov rdi, qword [pThreadID1]
mov rsi, NULL
call pthread_join
;create the second thread with id = pThreadID2
mov rdi, pThreadID2
mov rsi, NULL
mov rdx, thread2
mov rcx, NULL
call pthread_create
;join the 2nd thread
mov rdi, qword [pThreadID2]
mov rsi, NULL
call pthread_join
;print value block
其中 thread1
包含循环,其中 value
递增 MAX/2
次:
global thread1
thread1:
mov rcx, qword [MAX]
shr rcx, 1
thread1.loop:
mov eax, dword [value]
inc eax
mov dword [value], eax
loop thread1.loop
ret
和thread2
类似。注意:thread1
和 thread2
共享 变量 value
。
我将上面的程序汇编编译如下:
yasm -g dwarf2 -f elf64 Parallel.asm -l Parallel.lst
gcc -g Parallel.o -lpthread -o Parallel
然后我使用 time命令以了解经过的执行时间:
time ./Parallel
我明白了
value: +100000000
real 0m0.482s
user 0m0.472s
sys 0m0.000s
好的。在上面的程序中,我创建了一个线程,等待它完成,然后才创建第二个线程。不是最好的“线程”,不是吗?所以我改变了程序中的顺序如下:
;create thread1
;create thread2
;join thread1
;join thread2
我希望在这种情况下耗时会更少,但我明白了
value: +48634696
real 0m2.403s
user 0m4.772s
sys 0m0.000s
我明白为什么 value
不等于 MAX
但我不明白的是 为什么在这种情况下耗时明显更多 ?我错过了什么吗?
我决定通过为每个变量使用不同的变量来排除 thread1
和 thread2
之间的重叠,然后只添加结果。在这种情况下,“并行”顺序给出的运行时间较少(与之前的结果相比),但无论如何,大于“系列”顺序。
仅显示更改
现在有两个变量 --- 每个线程一个。
section .data
value1: dd 0
value2: dd 0
每个线程负责增加自己的值。
global thread1
thread1:
mov rcx, qword [MAX]
shr rcx, 1
thread1.loop:
mov eax, dword [value1]
inc eax
mov dword [value1], eax
loop thread1.loop
ret
thread2
类似(将 1 替换为 2)。
假设评论代表问题开头的代码部分的相应代码块,程序如下。
平行订单;create thread1
;create thread1
;join thread1
;join thread2
mov eax, dword [value]
add eax, dword [value1]
add eax, dword [value2]
mov dword [value], eax
结果
value: +100000000
Performance counter stats for './Parallel':
3078.140527 cpu-clock (msec)
1.586070821 seconds time elapsed
系列订单
;create thread1
;join thread1
;create thread2
;join thread2
mov eax, dword [value]
add eax, dword [value1]
add eax, dword [value2]
mov dword [value], eax
结果
value: +100000000
Performance counter stats for './Parallel':
508.757321 cpu-clock (msec)
0.509709406 seconds time elapsed
最佳答案
同时运行两个线程的版本速度较慢,因为运行代码的两个内核将竞争包含计数器值的缓存行。缓存行将不得不在两个核心之间来回移动,每次需要 10s 个周期,并且在移回另一个核心之前只会发生一些增量。将其与单线程情况相比,在单线程情况下,增量可以每 ~5 个周期发生一次1,受存储转发延迟和慢速 loop
指令限制。
对于线程递增共享值的情况以及它们不同的其他情况都是如此。它甚至适用于后一种情况,因为值 value1
和 value2
被声明为占据内存中的连续位置,因此出现在同一缓存行中。由于一致性发生在缓存行粒度上,这种所谓的“虚假共享”效应类似于真实共享(第一种情况)。
您提到虽然真共享和假共享情况都比单线程情况慢得多,但真共享情况仍然比假共享情况更慢。我原以为,在没有测试的情况下,这两种情况在性能方面是等效的,但它们没有意义:虽然两者都遭受上述缓存行抖动,但真正的共享情况可能还遭受额外的内存顺序清除 - 尽管确切的机制尚不清楚。
关于performance - 在 x86_64 汇编程序 (yasm) 中使用 POSIX 线程库需要更多的执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49475380/
在 Android 中集成 FFMPEG 库时出现上述错误。以下是屏幕截图。有人可以帮我整合这个库吗?我正在使用 Ubuntu OS 来实现这一点。 最佳答案 只需安装yasm sudo apt-ge
构建将近半小时后,出现以下错误。到目前为止,谷歌搜索没有任何帮助...... In file included from external/chromium_org/third_party/yasm/
我正在尝试通过 brew 安装 ffmpeg。我用 yasm 得到的错误是 “错误:在安装 ffmpeg 之前,您必须‘brew link pkg-config yasm’” 这样做时,我被告知我的权
org 0x7c00是在平面二进制文件中获取正确绝对地址的正常方法,但我对我希望使用的另一种方法感到好奇。 我尝试使用section boot vstart=0x7c00 align=1告诉YASM正
我有一个 x86_64 汇编程序,我试图在 Linux 上调试,但是当我尝试使用 gdb 时,它会随机跳过并循环执行相同的指令对或重复指令。它还似乎根据我设置断点的位置循环执行不同的指令。 我试着在线
我遇到了一个奇怪的问题。我试图安装 x264。当运行 sudo ./configure --enable-shared 时,它给出了: 找不到汇编器最低版本是 yasm-0.7.0如果您真的想在没有
我正在尝试为使用 的英特尔语法编写的 x86_64 汇编源代码64 位寄存器 .我使用以下命令行标志: yasm foo.asm -a x86 -m amd64 我不断收到以下错误: warning:
假设我声明了以下内容: section .bss buffer resb 1 这些说明位于.text部分: mov al, 5 ; mov-i
我想在c代码中调用ASM函数,如何将参数传递给ASM代码? #include extern int * asm_mod_array(int *ptr,int size); int main()
我需要 Microsoft Visual 2015 中的 Windows 10 中的 YASM 软件,谁能告诉安装 yasm 的步骤。 我已经使用了下面的链接。 https://github.com/
我有一个以原始模式读取字符的程序。也就是说,任何输入的字符都会被立即读取,而不是被缓冲。 我想知道如何执行退格。也就是说,当我按下退格键时,它应该删除左边的字符并将光标向左移动一位。 我尝试输出一个退
我有一个以原始模式读取字符的程序。也就是说,任何输入的字符都会被立即读取,而不是被缓冲。 我想知道如何执行退格。也就是说,当我按下退格键时,它应该删除左边的字符并将光标向左移动一位。 我尝试输出一个退
我正在尝试让 libtool 和 yasm 一起工作。 yasm 从我的 .asm 源创建正确的 .o 文件,但我不知道如何获取 libtool 构建相关的 .lo 和 .dep 文件。它想要构建共享
这个问题在这里已经有了答案: Can't run executable linked with libc (1 个回答) 关闭 2 年前。 当尝试在 linux (x86-64) 上从汇编代码 (y
我已经使用 yasm 汇编了代码,并链接到我的 C++ 程序,但我无法在 gdb 中对来自汇编语言文件的符号设置断点。 命令行可能不是很清楚,但我们开始吧: "g++" -ftemplate-dep
我正在尝试在 64 位 Linux 上运行的 NASM 中实现一个数组的选择排序。 数组声明为: section .bss strbuf resb 10 small resb 1 ; curre
我正在尝试使用 yasm 汇编下面的代码。我在 yasm 报告错误“错误:操作数 2 的大小无效”的地方添加了“此处”注释。为什么会发生这个错误? segment .data a db 25
我有一个关于 nasm 及其与 C++ 的链接的问题。我将一个小测试函数声明为 extern "C"void __cdecl myTest( byte i1, byte i2, int stride,
我正在尝试编写一个即时编译器,但我有一段代码不想工作。我的平台是 x86-64 ubuntu。 我在 yasm 中编写了以下代码: bits 64 mov rdx, 1 mov rcx, 'A' mo
我想在 yasm 程序中使用 POSIX 线程(或简称 pthread)库实现并行处理。 代码 这是我程序中最重要的部分。 section .data pThreadID1 dq
我是一名优秀的程序员,十分优秀!