这在很大程度上是一个理论问题,我确实有一个实际目的。在投入实践之前,我首先寻找一些概念性的答案,因为也许这个想法本身没有意义。
想象一下完全基于 JavaScript 的幻灯片。用户在屏幕上看到一个大图像,然后单击以移至下一个大图像。单击后,下一张图像将被加载并插入到 DOM 中,替换上一张图像。
我最近了解到预取指令可以帮助加快接下来很可能使用的资源的加载速度。请注意,我说的是资源,而不是页面。幻灯片是单页。
在图像幻灯片中,很明显很可能需要下一张图像,因此如果 image1 在屏幕上,我可以动态地将其添加到 DOM 中:
<link rel="prefetch" href="http://img.mysite.com/img2.jpg">
Run Code Online (Sandbox Code Playgroud)
我对这个想法的疑问:
我进行了大量搜索,但无法找到有关动态注入预取提示的特定情况的答案。
在 iOS 模拟器上测试时,我似乎每次打开应用程序时都会下载图像。这是预期的行为吗?
这三个图像最初是预取的,每当我引用该 URI 时都会使用缓存,但一旦我重新加载应用程序,一切似乎都会重置。
以下是我如何在组件中使用它的一些片段。
prefetchImages(images) {
let p = [];
images.map((url) => {
p.push(Image.prefetch(url).then(() => {
console.log('image prefetched:', url);
}));
});
return Promise.all(p);
}
this.prefetchImages([
'http://domain.com/myimg1.jpg',
'http://domain.com/myimg2.jpg'
])).then((a) => {
console.log('all images have been prefetched');
});
Run Code Online (Sandbox Code Playgroud)
我只是想知道即使在应用程序重新启动后图像是否也会被缓存。
理想情况下,我想下载一些资产一次,并将它们保留在磁盘上一段合理的时间。
是否Image.prefetch在幕后检查 HTTP 状态代码?我不知道如何通过模拟器记录网络请求来查看。我想知道应用程序重新启动时是否会收到304 Not Modified,或者是否始终收到200。任何帮助表示赞赏。
我注意到,对于我尝试运行的模型,我的 GPU 利用率仅为 30% 左右,而且通常由于 I/O,30% 的利用率会与 0% 利用率交替出现。为了解决添加到我的代码中的 I/OI,tf.contrib.data.prefetch_to_device如下所示:
dataset = tf.data.TFRecordDataset(self.filenames, "ZLIB", 384 * 1024 * 1024)
dataset = dataset.map(parse_func, 6)
dataset = dataset.prefetch(6)
dataset = dataset.apply(tf.contrib.data.prefetch_to_device("/gpu:0", 12))
#dataset = dataset.apply(tf.contrib.data.prefetch_to_device("/gpu:0", 2))
#dataset = dataset.apply(tf.contrib.data.prefetch_to_device("/gpu:0", 6))
self.iterator = dataset.make_initializable_iterator()
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我在尝试解决此问题时做了一些事情,包括:
buffer_size参数(对时间没有影响:我尝试了 12、6、2 和 1)dataset.prefetch行,以防它以某种方式干扰设备级预取(我也尝试了较小的数字,例如 2 和 1)当我为训练计时时,我没有发现这些变化有任何有意义的差异。此外,GPU 利用率继续遵循相同的模式,交替使用 0% 和 30% 的利用率。我还应该尝试什么?为什么使用 GPU 预取根本不会影响性能?感谢您的任何建议。
我有一个网站,网页上有一些<link rel="preload" href="...标签,我还想在其中添加尽可能严格的 CSP 标头,并且作为我想使用的一部分default-src 'none'
prefetch-src目前 Chrome 支持预取,但仅支持功能标志后面的 CSP 指令。因此,我可以使用该功能,但不能配置它周围的安全性,因此当前default-src 'none'所有预取调用都被阻止。
我能找到的唯一解决方案是更改default-src 'none'为default-src 'self',但这当然会降低安全性,因为许多不需要的资源可能无法加载。
有没有人找到解决这个问题的方法?
我想在 React Router 中为组件添加预取,但目前该组件是动态导入。添加 webpackprefetch= true 不起作用。因此想知道将 webpackprefetch= true 添加到 React 路由器的最佳方法是什么。
我尝试使用:
const SCHEDULES = () => import(/* webpackPrefetch: true / / webpackChunkName: "SchedulesPage" */ "./schedules/Schedules");
Run Code Online (Sandbox Code Playgroud)
但这并没有创建一个组件。
当前代码:
const SCHEDULES = () => import(/* webpackPrefetch: true / / webpackChunkName: "SchedulesPage" */ "./schedules/Schedules");
Run Code Online (Sandbox Code Playgroud)
<Switch>
{ /* Schedules page */ }
<Route exact path={ `${match.url}/schedules` } component={ Schedules } />
</Switch>Run Code Online (Sandbox Code Playgroud)
在大型 React SPA 中,我希望当用户打开/使用特定屏幕/功能时加载一些代码块。我们的许多 React 组件都是延迟加载的const Component=React.lazy(() => import('./lazyCode'))
我想在渲染时获取并改善用户体验延迟。由于 SPA 的规模和复杂性,我不想太早加载其中任何一个。
例如,我想预加载下一个反应组件(及其依赖项),而“下一个”是基于用户输入的动态和条件。
Webpack 支持 ES6 import(/* webpackPrefetch: true */ './path/to/LoginModal.js'); 但是,它没有附带 API。实际上并不清楚什么时候会触发预取。
我可以对import(pathToJs[i])链进行编程,但这不适用于<link prefetch>浏览器中的网络优先级。
Webpack 不提供 API 来获取要加载的实际 URL,因此我<link prefetch>自己也无法做到这一点。
我们可以为托管的吐出块延迟加载执行任何代码模式吗?
我似乎有一些关于如何在 Django 中以前向和后向关系预取相关字段的示例,但我怀疑如果我们想预取相关模型的所有字段,如何应用它。
例如,如果我想从以下模型中获取所有内容,使用HealthCheck作为起点。哪一个是实现这一目标的最优化查询?
class HealthCheck(models.Model):
id = models.Integer()
person = models.ForeignKey('Person')
class Person(models.Model):
profile = models.ForeignKey('Profile')
vaccines = models.ManyToManyField('vaccines', through='PersonVaccines')
class Profile(models.Model):
name = models.CharField(max_length=16)
class PersonVaccines(models.Model):
person = models.ForeignKey(Person)
vaccine = models.ForeignKey('Vaccine')
class Vaccine(models.Model):
name = models.CharField(max_length=16)
Run Code Online (Sandbox Code Playgroud)
我尝试过类似的方法,但似乎不起作用:
from django.db.models import Prefetch
HealthCheck.objects.filter(id=1).prefetch_related(
Prefetch(
'person__vaccines',
queryset=PersonVaccines.objects.select_related('person', 'person__profile', 'vaccine')
)
)
Run Code Online (Sandbox Code Playgroud)
如何预取所有相关内容?
我正在尝试了解LLC-prefetch-missesSandy Bridge 性能事件的含义。
从linux内核源代码我看到了事件的定义:
\n[ C(OP_PREFETCH) ] = {\n [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS,\n [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_L3_MISS,\n},\nRun Code Online (Sandbox Code Playgroud)\n其中:\nSNB_DMND_PREFETCH = (SNB_PF_DATA_RD|SNB_PF_RFO)指向事件寄存器的位 4-5,而\nSNB_L3_MISS = (SNB_DRAM_ANY|SNB_NON_DRAM)指向事件寄存器的位 22-36。
阅读Intel\xc2\xae 64 and IA-32 Architectures Software Developer\xe2\x80\x99s Manual,第 3 卷,第 18.3.4.5 章,我发现:
\nSNB_DMND_PREFETCH代表事件寄存器的“Request_Type”字段和SNB_L3_MISS“Response_Type”字段MSR_OFFCORE_RSP_x
要求:
\n\n回复:
\n\n但是,我无法理解预取上下文中“响应”的含义。
\n此外,我在一些课程幻灯片中发现了这个定义:
\nPrefetch Hit: Prefetched line that was hit in …
阅读何时应该使用预取?中接受的答案后 以及预取示例中的示例?,我在理解何时实际使用预取方面仍然存在很多问题。虽然这些答案提供了预取很有用的示例,但它们没有解释如何在实际程序中发现它。看起来像是随机猜测。
我特别对 intel x86 的 C 实现(prefetchnta、prefetcht2、prefetcht1、prefetcht0、prefetchw)感兴趣,这些实现可以通过 GCC 的__builtin_prefetch内在函数访问。我想知道:
perf。在这种情况下,什么指标(或它们之间的关系)表明有机会通过软件预取来提高性能?for (int i = 0; i < n; i++) {
// some code
double x = a[i];
// some code
}
Run Code Online (Sandbox Code Playgroud)
我应该在加载之前还是之后放置预取a[i]?它应该指向前方多远a[i+m]?我是否需要担心展开循环以确保我仅在缓存行边界上预取,或者它几乎是免费的,就像nop数据已经在缓存中一样?是否值得__builtin_prefetch连续使用多个调用来一次预取多个缓存行?
是否可以对 PCIe BAR 中的 MMIO 区域支持的地址(并通过 UC 或 WC 页表条目映射)发出预取?我目前正在对该地址发出负载,这会导致超线程停滞相当长一段时间。有一个非临时访问提示 via PREFETCHNTA,所以看起来这可能是可能的。
如果可能的话,您是否知道预取值存储在哪里以及在我能够为其发出加载之前什么可能导致它变得无效?例如,如果我针对sfence不相关的内容发出同步指令,这是否会导致预取值失效?
来自英特尔软件开发手册:
“来自不可缓存或 WC 内存的预取将被忽略......应该注意的是,处理器可以自由地推测性地从系统内存区域获取和缓存数据,这些区域被分配了允许推测性读取的内存类型(即 WB、WC和 WT 内存类型)。
MMIO 区域所在的 PCIe BAR 被标记为可预取,因此我不确定这是否意味着预取将与上面手册中的语言一起使用。
prefetch ×10
javascript ×3
caching ×2
reactjs ×2
webpack ×2
x86 ×2
atomic ×1
c ×1
django ×1
gpu ×1
html ×1
http ×1
image ×1
io ×1
linux ×1
memory ×1
pci-e ×1
perf ×1
performance ×1
preload ×1
profiling ×1
react-native ×1
tensorflow ×1
typescript ×1