在索引结构的核心,我发现自己想知道是否可以针对以下问题进行优化:

我有一个大的(几GB的RAM)数组的小结构(在RAM中),我有一个较小的索引数组(大约10e4个元素).指数几乎随机扩散.我有一个独立的秩序(对于数学家来说是“联想的”),例如“总和”.

我想收集从小数组中指定的索引从大数组中检索的值.

目前,我花费大部分时间从内存中获取(由于索引是随机扩展的,而且表格很大,所以存在很多缓存未命中,但是由于我对索引的了解应该有一些可用的预取).我发现很难确定一些预取优化是否正在进行,或者我可以从这样的优化中获得多少加速?

所以我的问题是,从已知的内存位置获取最快的方法是什么.有没有一些黑暗的编程魔法呢?有没有一些架构/平台具体的方法呢?我正在寻找c或c#解决方案.

解决方法

在不知道有关您的问题或您当前实现的其他任何内容的情况下,提高性能(在某种程度上)的一个(有些)简单的方法是手动预取您的“sum”函数将要运行的值.

现在忽略了架构和编译器的细微差别,手动预取可能如下所示:

SmallStruct values [value_count] = {/*whatever*/};
int indices [index_count] = {/*whatever*/};
...

SmallStruct v = values[indices[0]];
for (int i = 1; i < index_count; ++i)
{
    SmallStruct v_next = values[indices[i]];
    DoSomethingWith (v); // Note the *v*
    v = v_next; // You don't want to copy,but this is the simplest form
}
DoSomethingWith (v); // Do the final item

以上是最简单的预取形式.您可以展开循环一点,以避免上面提到的复制,也可能希望做一个以上的单独的预取.

这种优化是有效的,因为大多数(所有的)现代架构可以在飞行中具有多个存储器请求,这意味着这些请求是重叠的,并且那些(大概是未被缓存的)请求的平均等待时间被它们的并发划分(这是一个很好的事情!)所以,你有多少未使用的缓存行是不关键的重要的因素是内存系统在任何给定时间可以持续的并发内存读取的数量.

关于缓存线的影响的注释

上述(毫无疑问的简单)代码忽略了两个非常重要的事实:整个SmallStruct不能在一个内存访问(从cpu的角度)读取,这是一件坏事,而且内存总是以缓存行为单位读取(64或128字节,这些天)反正这是非常好的!

因此,我们可以读取一个单字节,而不是将整个值[indices [i]]读入v_next,而是假设值数组正确对齐,将加载大量内存(一个完整的高速缓存行)并在手边进行最终处理.

两个重点:

>如果您的SmallStruct实际上并不完全符合缓存行,则必须对其成员进行重新排列,以确保其在DoSomethingWith()中所需的部分是连续的并打包并适合一个缓存行.如果仍然不适合,您应该考虑将算法分成两个或更多个遍,每个通过操作符合一个缓存行中的数据.
>如果您只是从下一个值中读取一个字节(或一个字,或任何一个),请确保编译器不会优化该读取!

替代实施

上面的第二点可以用代码表示,如下所示:

touch (&values[indices[0]]);
for (int i = 0; i < index_count; ++i)
{
    if (i + 1 < index_count)
        touch (&values[indices[i + 1]]);

    DoSomethingWith (values[indices[i]]);
}

touch()函数在语义上是这样的(虽然实现可能会更多地涉及到)

void touch (void * p)
{
    char c = *(char *)p;
}

要预取多个值,您可以执行以下操作:(更新:我将代码更改为(我相信)更好的实现.)

const int PrefetchCount = 3;

// Get the ball rolling...
for (int j = 0; j < PrefetchCount; ++j)
    touch (&values[indices[j]]);

for (int i = 0; i < index_count; ++i)
{
    if (i + PrefetchCount < index_count)
        touch (&values[indices[i + PrefetchCount]]);

    DoSomethingWith (values[indices[i]]);
}

再次注意,上述所有实现都非常简单和简单.此外,如果您预取的太多,您可以吹一下L1缓存和您的表现.

进行实际预取

x86-64 cpu有一条指令,用于要求cpu将高速缓存行内存数据预取到缓存中.实际上,使用这条指令,您可以向cpu提示该应用程序将使用该特定内存位置,并且cpu将尝试将其带入缓存.如果您足够快,数据将在您需要时准备就绪,您的计算不会停顿.

该指令是PREFETCH *,您可以使用编译器特定的内在函数,而不是使用汇编.这些内在函数在Microsoft和Intel C编译器中被称为_mm_prefetch,在GCC上称为__builtin_prefetch. (如果你最终使用这个,只要记住你想要最低级别的预取,即T0.)

请注意,这些进入我上面使用的触摸功能的实现.

我知道没有一个可重复使用的图书馆.此外,我不熟悉C#库以了解这些是否可用.

c# – 最快的方法来获取内存值的数组的更多相关文章

  1. 详解使用双缓存解决Canvas clearRect引起的闪屏问题

    这篇文章主要介绍了详解使用双缓存解决Canvas clearRect引起的闪屏问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. html5使用canvas实现弹幕功能示例

    这篇文章主要介绍了html5使用canvas实现弹幕功能示例的相关资料,需要的朋友可以参考下

  4. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. 前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

    这篇文章主要介绍了前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. 详解前端HTML5几种存储方式的总结

    本篇文章主要介绍了前端HTML5几种存储方式的总结 ,主要包括本地存储localstorage,本地存储sessionstorage,离线缓存(application cache),Web SQL,IndexedDB。有兴趣的可以了解一下。

  8. ios – parse.com用于键,预期字符串的无效类型,但是得到了数组

    我尝试将我的数据保存到parse.com.我已经预先在parse.com上创建了一个名为’SomeClass’的类.它有一个名为’mySpecialColumn’的列,其数据类型为String.这是我尝试使用以下代码保存数据的代码:如果我运行这个我得到:错误:密钥mySpecialColumn的无效类型,预期字符串,但得到数组这就是我在parse.com上的核心外观:有谁知道我为什么会收到这个错误?

  9. ios – 上下文类型’NSFastEnumeration’不能与数组文字一起使用

    斯威夫特3,你会这样做吗?解决方法正如您所发现的,您不能使用as-casting将数组文字的类型指定为NSFastEnumeration.您需要找到一个符合NSFastEnumeration的正确类,在您的情况下它是NSArray.通常写这样的东西:

  10. 在iOS上,缓存绘制的屏幕图像并显示它的最快方法是什么?

    我没有让drawRect每次重绘数千个点,我认为有几种方法可以“在屏幕上缓存图像”和任何其他绘图,我们将添加到该图像,并在drawRect时显示该图像:>使用BitmapContext并绘制到位图,并在drawRect中绘制此位图.>使用CGLayer并在drawRect中绘制CGLayer,这可能比方法1快,因为此图像缓存在图形卡中(并且它不会计入iOS上“内存警告”的RAM使用情况?

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部