Проблема в том, что событие FileReader onLoadEnd является асинхронным, поэтому оно не будет работать внутри функции карты.
Один из способов решения вашей проблемы - обернуть вашу функцию Обещанием, создать наблюдаемое из обещания с из и использовать оператор switchMap для сопоставления вашего наблюдаемый к новому от обещания.
Теперь, когда вы подпишетесь на полученную наблюдаемую информацию, она выдаст результат из FileReader. Если он отклоняется, вы можете получить ошибку с помощью второго параметра метода подписки.
import {from} from 'rxjs'
import {switchMap} from 'rxjs/operators'
transform(url: string, asBase64: boolean): Observable {
return this.http
.get(url, {responseType: 'blob'})
.pipe(
switchMap(
val => from( // create the observable from a promise
new Promise((resolve, reject) => { //create a new Promise
if (!asBase64) {
resolve(this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))) //resolve if base64
}
const reader = new FileReader();
reader.readAsDataURL(val);
reader.onloadend = () => resolve(reader.result); //resolve when it finishes to load the file
reader.onerror = () => reject(reader.error); //rejects if there was an error while reading the file
})
)
)
);
}
...
const file$ = transform(url, asBase64)
file$.subscribe(
(file) => console.log(file), // do stuff with the file here
(error) => console.log(error) // there was an error while reading the file
)
Почти невозможно найти спецификации в кэшах Intel. Когда я преподавал класс кэшам в прошлом году, я спросил друзей в Intel (в группе компилятора), и они не могли найти спецификации.
Но ожидайте!!! Jed, благословите его душу, говорит нам, что в системах Linux, можно сжать большую информацию из ядра:
grep . /sys/devices/system/cpu/cpu0/cache/index*/*
Это даст Вам ассоциативность, установит размер и набор другой информации (но не задержка). Например, я узнал, что, хотя AMD рекламирует их кэш 128K L1, моя машина AMD имеет разделение I и кэш D 64K каждый.
Два предложения, которые являются теперь главным образом устаревшими благодаря Jed:
AMD публикует намного больше информации о своих кэшах, таким образом, Вы можете, по крайней мере, получил некоторую информацию о современном кэше. Например, прошлогодние кэши AMD L1 произнесли два слова на цикл (пик).
Инструмент с открытым исходным кодом valgrind
имеет все виды моделей кэша в нем, и это неоценимо для профилирования и понимания поведения кэша. Это идет с очень хорошим инструментом визуализации kcachegrind
который является частью SDK KDE.
Например: в 3 квартале 2008 центральные процессоры AMD K8/K10 используют 64-байтовые строки кэша с 64 КБ каждый кэш разделения L1I/L1D. L1D с 2 путями ассоциативный и эксклюзивный с L2 с задержкой 3 циклов. Кэш L2 с 16 путями ассоциативный, и задержка является приблизительно 12 циклами.
Центральные процессоры семейства Бульдозера AMD используют разделение L1 с ассоциативным L1D с 4 путями на 16 кибибитов на кластер (2 на ядро).
Intel CPUs сохранял L1 тем же в течение долгого времени (от Pentium M к Haswell к Skylake и по-видимому многим поколениям после этого): Разделите 32 КБ каждый я и кэши D, при этом L1D будь с 8 путями ассоциативный. 64-байтовые строки кэша, соответствуя размеру пакетной передачи DRAM DDR. Задержка использования загрузки является ~4 циклами.
Также посмотрите, что x86 отмечает Wiki для ссылок на большее количество производительности и микроархитектурных данных.
Вы смотрите на потребительские спецификации, не спецификации разработчика. Вот документация, которую Вы хотите. Размеры кэша варьируются подмоделями семейства процессоров, таким образом, они обычно не находятся в руководствах разработки IA-32, но можно легко искать их на Newegg и таком.
Править: Более конкретно: Глава 10 Объема 3 А (Системное Руководство по программированию), Глава 7 Справочника Оптимизации, и потенциально что-то в кэширующем страницу руководстве TLB, хотя я предположил бы, что каждый далее вне L1, чем Вы, заботится о.
Я сделал еще некоторое исследование. Существует группа в Швейцарской высшей технической школе Цюриха, которая создала инструмент оценки результатов деятельности памяти, который смог получать информацию о размере, по крайней мере (и возможно также ассоциативность) L1 и кэшей L2. Программа работает путем попытки различных шаблонов чтения экспериментально и измерения получающейся пропускной способности. Упрощенная версия использовалась для популярного учебника Bryant и O'Hallaron.
Кэши L1 существуют на этих платформах. Это почти определенно останется верным, пока шина памяти и скорости системной шины не превысят скорость ЦП, который является вероятным далеко.
В Windows можно использовать GetLogicalProcessorInformation для получения некоторого уровня информации о кэше (размер, размер строки, ассоциативность, и т.д.) Исключая версией на Win7 даст еще больше данных, как который доля ядер который кэш. CpuZ также дает эту информацию.
Местность Ссылки оказывает основное влияние на производительность некоторых алгоритмов; размер и скорость L1, L2 (и на более новых центральных процессорах L3) кэш, очевидно, играют значительную роль в этом. Умножение матриц является одним таким алгоритмом.
Intel Manual Vol. 2 указывает следующую формулу для вычислений размера кэша:
Этот Размер кэша в Байтах
= (Пути + 1) * (Разделы + 1) * (Line_Size + 1) * (Наборы + 1)
= (EBX [31:22] + 1) * (EBX [21:12] + 1) * (EBX [11:0] + 1) * (ECX + 1)
, Где Ways
, Partitions
, Line_Size
и Sets
запрашиваются с помощью cpuid
с eax
набор к 0x04
.
Обеспечение объявления
x86_cache_size.h
заголовочного файла:
unsigned int get_cache_line_size(unsigned int cache_level);
реализация смотрит следующим образом:
;1st argument - the cache level
get_cache_line_size:
push rbx
;set line number argument to be used with CPUID instruction
mov ecx, edi
;set cpuid initial value
mov eax, 0x04
cpuid
;cache line size
mov eax, ebx
and eax, 0x7ff
inc eax
;partitions
shr ebx, 12
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;ways of associativity
shr ebx, 10
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;number of sets
inc ecx
mul ecx
pop rbx
ret
, Который на моей машине работает следующим образом:
#include "x86_cache_size.h"
int main(void){
unsigned int L1_cache_size = get_cache_line_size(1);
unsigned int L2_cache_size = get_cache_line_size(2);
unsigned int L3_cache_size = get_cache_line_size(3);
//L1 size = 32768, L2 size = 262144, L3 size = 8388608
printf("L1 size = %u, L2 size = %u, L3 size = %u\n", L1_cache_size, L2_cache_size, L3_cache_size);
}