我正在尝试在快速排序中使用子进程,以便左半部分在一个子进程中排序,右半部分在另一个子进程中排序。我在 shmget 实现之前就让它工作了,但现在我相信我在某个地方破坏了数组,因为在打印数组后我的所有值都变为零。抱歉,如果我在某个地方犯了一些愚蠢的错误,我正在尝试学习如何使用 fork 和 shmget 但遇到了一些麻烦。我试图将一个文本文件作为命令行参数,并给出一个分隔符,例如“;” 我必须删除分隔符并识别之间的数字,将它们放入数组中并使用子进程对它们进行排序。我的解析工作正常,快速排序工作正常,但现在我正在尝试实现共享内存,但遇到了一些问题。
谢谢
我看过几个不同的示例,但这主要基于 geeksforgeeks 示例,其中使用 fork 进行合并排序。 https://www.geeksforgeeks.org/concurrent-merge-sort-in-shared-memory/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "fileParser.h"
#include "dataManagement.h"
int main(int argc, char *argv[]){
char *file = argv[1];
char delimiter = argv[2][0];
MyArray *theArray = getArray(file, delimiter);
size_t SHM_SIZE = theArray->length;
theArray->key = IPC_PRIVATE;
if((theArray->shmid = shmget(theArray->key, SHM_SIZE, IPC_CREAT | 0666)) < 0){
perror("shmget");
_exit(-1);
}
if ((theArray->shm_array = shmat(theArray->shmid, NULL, 0)) == (int *) -1)
{
perror("shmat");
_exit(1);
}
printArray(theArray, theArray->length);
quickSortFork(theArray, 0, …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 U-Space 分配的虚拟内存 (shm) 映射到特定的 DIMM。我成功地使用 get_user_pages_remote作为指向虚拟内存的起始指针来检索 pfns,然后使用page_to_pfn将每个页面结构转换为 pfn (顺便说一句,这些 pfns 进一步用于为专有帧捕获器设备创建分散收集表并完美地完成工作)。但是,我没有找到一种方法来识别每个物理地址 (pfn) 源自哪个物理 DIMM (DRAM)。互联网搜索产生了一些 DRAM 地址映射方案,但所有这些方案都旨在处理模块内部导航,即:行、列、库、通道和等级,并且所有前者都依赖于内存提供商架构,例如https://www.betriebssysteme .org/wp-content/uploads/2017/04/Hillenbrand.pdf。另一方面,深入研究 SMBIOS 规范https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf,可以从 /dev/mem (dmidecode - t 内存),但是我无法将这两个信息源链接在一起并最终映射页面。
任何建议将被认真考虑。
谢谢,
约尔。
我有几个执行mmap()特定大小(0x8000)的进程。我只想在这些进程之间共享部分内存空间,如下图所示:
0x0 0x2000-0x3000 0x8000
p1: [MEM. PRIVATE] [MEM. SHARING] [MEM. PRIVATE]
p2: [MEM. PRIVATE] [MEM. SHARING] [MEM. PRIVATE]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,分配的内存mmap()必须仅在 0x2000-0x3000 范围之间共享。其他部分是私有的(MEM.PRIVATE)。
调用后是否有系统调用来执行共享mmap()?我事先尝试过shm_open(),但整个范围都是共享的。
我正在使用pthreads编写一个多线程演示程序,其中一个线程将数据加载到STL队列,另一个线程从中读取.听起来很琐碎,对吗?不幸的是,推入队列的数据正在消失.我不是多线程的新手,也不熟悉内存结构 - 然而,这让我很难过.
这些是我对队列本身的声明以及保护它的互斥锁,它们位于客户端代码包含的标头中:
static std::queue<int32_t> messageQueue;
static pthread_mutex_t messageQueueLock;
Run Code Online (Sandbox Code Playgroud)
程序启动时,它会使用进程共享属性初始化互斥锁:
pthread_mutexattr_t sharedAttr;
pthread_mutexattr_init(&sharedAttr);
pthread_mutexattr_setpshared(&sharedAttr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&messageQueueLock, &sharedAttr);
Run Code Online (Sandbox Code Playgroud)
然后它启动'生产者'线程和'消费者'线程,并让他们做他们的事情.生产者线程将新项目推送到队列,然后进入休眠状态.以下是向队列添加内容的行:
pthread_mutex_lock(&messageQueueLock);
messageQueue.push(message);
pthread_mutex_unlock(&messageQueueLock);
Run Code Online (Sandbox Code Playgroud)
然后它休眠并让消费者线程接管.但是,当使用者线程检查队列中的项目时,队列是神奇的空.
我已经使用gdb介绍了该程序.以下是我跑步的输出.您可以看到生产者向队列添加内容的位置,我打印队列的大小以确保它在那里,有一个上下文切换到消费者线程,我再次打印队列的大小,它是空的.看看这个:
(gdb) b main_ex.cpp:70
Breakpoint 1 at 0x100006a24: file main_ex.cpp, line 70.
(gdb) run
Starting program: a.out
Reading symbols for shared libraries ++. done
Creating the mutex.
Producer thread starting up.
PRODUCER: Creating a message to send.
PRODUCER: Adding the message to the queue.
[Switching to process 7432]
Breakpoint 1, yourProcess () at main_ex.cpp:70
70 pthread_mutex_lock(&messageQueueLock);
(gdb) …Run Code Online (Sandbox Code Playgroud) 我试着读了很多资源,CreateMappingFile但不幸的是我没有那么好的英语,所以我需要问一下如果是真的我得出的结论:
CreateMappingFile为虚拟内存中的文件制作类似RAM的结构,而不是RAM,因此这种结构(或任何被调用的)位于硬盘中,但是以可以传输到RAM的形式.当我们需要将此结构传输到我们使用的RAM时MapViewOfFile.
是对的吗?
我想了解操作系统中的这些IPC机制概念 - 共享内存,消息系统,套接字,RPC,RMI
不同的操作系统如何实现这些.特别是Android操作系统?
我正在尝试在共享内存中创建一个int数组和一个bool数组.到目前为止,我有以下代码运行没有错误,"显然"创建内存,但是我不确定我是否可以使用LPCTSTR来访问像数组一样的数据?有人可以解释一下这个问题的最佳方法,因为我发现MSDN非常缺乏和痛苦.
void createSharedMemory()
{
const char slotsName[]="Slots";
const char flagsName[]="Flags";
const LONG BufferSize = sizeof(int);
const LONG Buffers = 10;
const LONG FlagSize = sizeof(bool);
HANDLE hSlots = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, BufferSize * Buffers, SLOTSNAME);
assert(hSlots != NULL);
HANDLE hFlags = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, FlagSize * Buffers, flagsName);
assert(hSlots != NULL);
std::cout << "Created shared memory!" << std::endl;
}
int main(int argc, char* argv[])
{
createSharedMemory();
HANDLE hSlots;
LPCTSTR pSlots;
hSlots = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SLOTSNAME);
if(hSlots == NULL) …Run Code Online (Sandbox Code Playgroud) 我试图将一个相对较大的文件加载到内存中,并能够通过a访问它HANDLE,就像检索一样CreateFile().
加载文件
在内存中加载时更改多个属性
HANDLE我无法再次将文件保存到硬盘.
在MSDN上有一个例子,我可以在其中创建一个共享内存:遗憾的是,创建命名共享内存我不太确定这与我的赋值有多相关,因为函数检索的句柄是FileMapping句柄,缓冲区本身是一个LPCTSTR指针.
我正在尝试沿着2D矩阵的行方向实现缩减.我从stackoverflow上找到的代码开始(非常感谢Robert!)
thrust :: max_element比较cublasIsamax慢 - 更有效的实现?
上面的链接显示了一个在单行上执行缩减的自定义内核.它将输入行分为多行,每行有1024个线程.效果很好.
对于2D情况,一切都是相同的,除了现在有一个网格尺寸.所以每个块的y维度仍然是1.问题是当我尝试将数据写入每个块内的共享内存(在代码中的"max_idx_kernel_reduction_within_block"内核中)时,需要很长时间(超过(行数)*(在1行上执行减少所需的时间.我宁愿运行for循环).我知道我有很多元素,但我期待比这更快的东西.
我不认为内存访问模式是一个问题,但我听说TOTAL共享内存量可能是限制?:CUDA:合并全局内存访问速度比共享内存快吗?另外,分配大型共享内存阵列会减慢程序的速度吗?
任何使我的代码更快的建议(第一个内核是瓶颈)?非常感谢,非常感谢!!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <cuda_runtime.h>
#define NCOLS 163317 // number of columns
#define NROWS 8 // number of rows
#define nTPB 1024 // Threads per Block. nTPB should be a power-of-2
#define MAX_BLOCKS_X ((NCOLS/nTPB)+1) // # of blocks I will launch
#define MIN(a,b) ((a>b)?b:a)
#define FLOAT_MIN -1.0f // lowest anticipated number of the data. Values in array will be compared with this and updated …Run Code Online (Sandbox Code Playgroud) 我有一个C++程序,其任务是分析二进制数据流(通常是磁盘上的文件)并提取一些信息.此任务是"无记忆",意味着每个步骤的结果与前一步骤无关.因此,我想通过将数据提供给单独的线程以提高性能来加快速度.
目前,数据以1GB的块一次读取并保存在阵列中以避免I/O瓶颈.我应该分n块/数组中的数据(n线程数在哪里),还是由多个线程访问的单个数组不是问题?
我有一个C++程序,其任务是分析二进制数据流(通常是磁盘上的文件)并提取一些信息.此任务是"无记忆",意味着每个步骤的结果与前一步骤无关.因此,我想通过将数据提供给单独的线程以提高性能来加快速度.
目前,数据以1GB的块一次读取并保存在阵列中以避免I/O瓶颈.我应该分n块/数组中的数据(n线程数在哪里),还是由多个线程访问的单个数组不是问题?
编辑1:数据和anlaysis规范 我发现问题的措辞可能过于宽泛,正如其中一条评论所指出的那样.我会尝试更详细一点.
被分析的数据是由所谓的"时间 - 数字"转换器(TDC)生成的一系列无符号64位整数,存储关于它们注册的某些事件的时间戳信息.我的TDC有多个通道,因此每个时间戳都有关于触发哪个通道(前3位)的信息,无论是上升沿还是下降沿触发(第4位),以及实际时间(自上次TDC上电后的时钟周期,最后一次) 60位).
当然,时间戳按时间顺序保存在文件中.任务是在用户设置的特定时间窗口内找到频道之间的重合事件.因此,您继续阅读时间戳,当您在感兴趣的通道中找到两个时间距离小于设定值时,您会增加重合事件的数量.
这些文件可能非常大(几十GB),时间戳数量巨大(一个时钟周期为80 皮秒).
现在我只浏览整个文件一次,并且想法是用较小的片段"剪切",然后由不同的线程进行分析.切割之间可能发生的事件损失对我来说是可以接受的,因为,最多只有2到数十万.
当然,他们只会从文件/内存中读取数据.我可以在三个单独的变量中写出重合计数,然后在所有线程完成时将它们相加,如果这有助于避免同步问题.
我希望现在情况更清楚了.