Nutshell中的C#4(强烈推荐的btw)使用以下代码来演示MemoryBarrier的概念(假设A和B在不同的线程上运行):
class Foo{
int _answer;
bool complete;
void A(){
_answer = 123;
Thread.MemoryBarrier(); // Barrier 1
_complete = true;
Thread.MemoryBarrier(); // Barrier 2
}
void B(){
Thread.MemoryBarrier(); // Barrier 3;
if(_complete){
Thread.MemoryBarrier(); // Barrier 4;
Console.WriteLine(_answer);
}
}
}
Run Code Online (Sandbox Code Playgroud)
他们提到障碍1和4阻止这个例子写0和障碍2和3提供新鲜度保证:他们确保如果B在A之后运行,读_complete将评估为真.
我不是真的得到它.我想我明白为什么壁垒1和4是必要的:我们不想在写_answer进行优化,并放置在写后_complete(屏障1),我们需要确保_answer没有被缓存(光栅4) .我也认为我理解为什么Barrier 3是必要的:如果A在写完_complete = true之后才运行,B仍然需要刷新_complete以读取正确的值.
我不明白为什么我们需要障碍2!我的一部分说这是因为可能线程2(运行B)已经运行直到(但不包括)if(_complete),因此我们需要确保_complete被刷新.
但是,我不知道这有多大帮助.是不是仍然可以在A 中将_complete设置为true但是B方法会看到_complete的缓存(错误)版本?即,如果线程2运行方法B直到第一个MemoryBarrier之后,然后线程1运行方法A直到_complete = true但没有进一步,然后线程1恢复并测试是否(_complete) - 如果不导致错误 …
c# multithreading thread-safety shared-memory memory-barriers
我对如何在CUDA中使用共享和全局内存感到困惑,尤其是对于以下内容:
cudaMalloc(),我们得到一个指向共享或全局内存的指针吗?将变量存储在共享内存中与通过内核传递其地址相同吗?也就是说,而不是
__global__ void kernel() {
__shared__ int i;
foo(i);
}
Run Code Online (Sandbox Code Playgroud)
为什么不等同呢
__global__ void kernel(int *i_ptr) {
foo(*i_ptr);
}
int main() {
int *i_ptr;
cudaMalloc(&i_ptr, sizeof(int));
kernel<<<blocks,threads>>>(i_ptr);
}
Run Code Online (Sandbox Code Playgroud)关于全局与共享内存中的特定速度问题存在很多问题,但没有一个问题包含何时在实践中使用任何一个内容的概述.
非常感谢
如何在Java中等待和通知在C/C++中两个或多个线程之间的共享内存?我使用pthread库.
我想添加一个在Linux嵌入式系统上运行的服务(守护进程)使用的一些参数的网络控制.不需要过程调用,每个参数都可以以非常自然的方式进行轮询.共享内存似乎是一种很好的方法,可以将网络代码保留在守护程序之外,并限制对一组精心控制的变量的共享访问.
因为我不希望部分写入导致从未写过的值的可见性,所以我在考虑使用std::atomic<bool>和std::atomic<int>.但是,我担心这std::atomic<T>可能会以只适用于C++ 11线程而不是多个进程的方式实现(可能,甚至不包括OS线程).具体来说,如果实现使用存储在共享内存块之外的任何数据结构,则在多进程方案中,这将失败.
我确实看到一些要求,这些要求表明std::atomic不会存在嵌入式锁定对象或指向其他数据的指针:
原子积分专业化和专业化
atomic<bool>应具有标准布局.它们每个都有一个普通的默认构造函数和一个普通的析构函数.它们应各自支持聚合初始化语法.应该有原子类模板的指针部分特化.这些特化应具有标准布局,普通默认构造函数和普通析构函数.它们应各自支持聚合初始化语法.
在我看来,无关紧要的默认构造和破坏是排除关联的每个对象数据,无论是存储在对象内,还是通过指针成员变量,还是通过外部映射.
但是,我认为没有任何东西可以排除使用单个全局互斥/临界区(或者甚至是全局集合)的实现,只要集合元素不与单个原子对象相关联 - 这与缓存关联方案一致可用于减少虚假冲突).显然,使用全局互斥锁的实现对多个进程的访问会失败,因为用户将拥有独立的互斥锁,而不是实际上彼此同步.
是atomic<T>允许执行与进程间共享内存不兼容的实现,还是有其他规则使其安全?
我只是注意到,普通的默认构造使对象处于未就绪状态,并且需要调用atomic_init.标准提到了锁的初始化.如果这些存储在对象中(并且动态内存分配似乎不可能,因为析构函数仍然是微不足道的),那么它们将在进程之间共享.但我仍然担心全球互斥的可能性.
在任何情况下,保证atomic_init对共享区域中的每个变量进行单次调用似乎很难......所以我想我将不得不避开C++ 11原子类型.
我正在阅读各种IPC机制.我试图弄清楚场景,我们使用共享内存和我们使用命名管道(FIFO)的地方.
管道:多个进程可以写入,但只有一个进程可以读取.写操作是原子的.
共享内存:多个进程可以读写.并且用户还需要提供互斥以进行读写.
这是共享内存和管道应用的唯一区别吗?
我是shared_ptr的新手,我正试图弄清楚.reset()函数的确切功能.
#include <memory>
#include <stdio>
using namespace std;
class SomeClass{};
int main()
{
shared_ptr<SomeClass> sp (nullptr);
//do some stuff, sp now has 10 co-owners
cout << sp.use_count << endl;
sp.reset();
cout << sp.use_count << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
会输出
10
0
Run Code Online (Sandbox Code Playgroud)
因为我使用了reset函数是从内存中删除了所有实例吗?因为,我刚刚用sp消除了任何可能的内存泄漏?显然,这是一个我快速编写的玩具示例,对不起,如果有任何错误.
跟进情况:
shared_ptr<SomeClass> returnThis() {
shared_ptr<SomeClass> someObject(new SomeClass(/*default constructor for example*/) );
return someObject;
}
Run Code Online (Sandbox Code Playgroud)
在主要的地方:
shared_ptr<SomeClass> mainObject;
mainObject = returnThis();
Run Code Online (Sandbox Code Playgroud)
mainObject的使用次数是否为2,因为someObject是在函数中创建但从未清除过的?或者它是一个,并在返回值时自动完成清理?
我有一个 python 程序,我需要在其中加载和反序列化 1GB 的 pickle 文件。这需要 20 秒,我想要一种机制,可以随时使用泡菜的内容。我看过shared_memory但它的所有使用示例似乎都涉及 numpy 而我的项目不使用 numpy。使用shared_memory或以其他方式实现这一目标的最简单和最干净的方法是什么?
这就是我现在加载数据的方式(每次运行):
def load_pickle(pickle_name):
return pickle.load(open(DATA_ROOT + pickle_name, 'rb'))
Run Code Online (Sandbox Code Playgroud)
我希望能够在两次运行之间编辑模拟代码而无需重新加载泡菜。我一直在搞乱,importlib.reload但对于包含许多文件的大型 Python 程序来说,它似乎真的不太好用:
def main():
data_manager.load_data()
run_simulation()
while True:
try:
importlib.reload(simulation)
run_simulation()
except:
print(traceback.format_exc())
print('Press enter to re-run main.py, CTRL-C to exit')
sys.stdin.readline()
Run Code Online (Sandbox Code Playgroud) 在了解了这个主题之后,任何人都可以说,POSIX共享内存(shm_open)和POSIX映射文件(mmap)之间的真正区别是什么?
两者似乎都使用/ dev/tmpfs子系统,而不是旧的IPC机制.
那么在共享内存上使用mmap文件有什么好处吗?
谢谢.
有人可以解释为什么创造了ashmem吗?
我正在浏览mm/ashmem.c.就像我所知,内核正在考虑将ashmem作为文件支持的内存,可以是mmap'd.但是,为什么要去实施ashmem呢?似乎可以通过安装RAM fs然后使用filemap/mmap来共享内存来实现相同的功能.
我确信ashmem可以做更多花哨的东西 - 从查看代码,它似乎与固定/取消固定页面有关?
让我们说有一台4个CPU的计算机,每个CPU有2个核心,所以共有8个核心.由于我的理解有限,我认为在这种情况下所有处理器共享相同的内存.现在,最好直接使用openMP或使用MPI使其通用,以便代码可以在分布式和共享设置上工作.另外,如果我将MPI用于共享设置,那么与openMP相比性能会降低吗?