Linux内核性能架构:perf_event

Linux阅码场 2022-10-11 08:00

荣涛,csdn博主。

组件概述

Linux性能子系统在性能分析中非常有用。以下显示了这篇文章中的perf子系统componenet 。

“ perf”是可用于执行性能分析的用户程序。

仅暴露给用户空间的系统调用perfeventopen返回一个perf事件fd。该系统调用没有glibc包装器。更多信息可以在手册页中阅读。此功能是最复杂的功能之一。

“ perf_event”是内核中的核心结构。性能事件有几种类型,例如跟踪点,软件,硬件。

我们还可以通过perf event fd将eBPF程序附加到trae事件。

抽象层

以下显示了perf的抽象层。

每个类型的性能事件都有一个对应的PMU(性能监视单元)。例如,跟踪点pmu具有以下pmu。

  1. static struct pmu perf_tracepoint = {

    1. .task_ctx_nr = perf_sw_context,

    2. .event_init = perf_tp_event_init,

    3. .add = perf_trace_add,

    4. .del = perf_trace_del,

    5. .start = perf_swevent_start,

    6. .stop = perf_swevent_stop,

    7. .read = perf_swevent_read,

  2. };


与硬件相关的PMU具有与arch-spec有关的抽象结构,例如'struct x86_pmu'。与硬件相关的结构将读取/写入性能监视器MSR。

每个PMU都通过调用“ perf_pmu_register”进行注册。

性能事件上下文

性能可以监视cpu相关事件和任务相关事件。他们两个都可以有几个受监视的事件。因此,我们需要一个上下文来连接事件。这是“ perf_event_context”。

有两种上下文,软件和硬件,定义如下:

  1. enum perf_event_task_context {

  2. perf_invalid_context = -1,

  3. perf_hw_context = 0,

  4. perf_sw_context,

  5. perf_nr_task_contexts,

  6. };

对于CPU级别,上下文定义为“ perf_cpu_context”,并在“ struct pmu”中定义为percpu变量。

  1. struct pmu {

  2. ...

  3. struct perf_cpu_context __percpu *pmu_cpu_context;

  4. };


如果PMU是相同类型,则它们将共享一个“ struct perf_cpu_context”。

  1. int perf_pmu_register(struct pmu *pmu, const char *name, int type)

  2. {

  3. int cpu, ret, max = PERF_TYPE_MAX;


  4. mutex_lock(&pmus_lock);

  5. ...

  6. pmu->pmu_cpu_context = find_pmu_context(pmu->task_ctx_nr);

  7. if (pmu->pmu_cpu_context)

  8. goto got_cpu_context;


  9. ret = -ENOMEM;

  10. pmu->pmu_cpu_context = alloc_percpu(struct perf_cpu_context);

  11. if (!pmu->pmu_cpu_context)

  12. goto free_dev;


  13. for_each_possible_cpu(cpu) {

  14. struct perf_cpu_context *cpuctx;


  15. cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);

  16. __perf_event_init_context(&cpuctx->ctx);

  17. lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex);

  18. lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock);

  19. cpuctx->ctx.pmu = pmu;

  20. cpuctx->online = cpumask_test_cpu(cpu, perf_online_mask);


  21. __perf_mux_hrtimer_init(cpuctx, cpu);


  22. cpuctx->heap_size = ARRAY_SIZE(cpuctx->heap_default);

  23. cpuctx->heap = cpuctx->heap_default;

  24. }


  25. ...

  26. }

下图显示了此帖子中的相关结构。


对于任务级别,“ task_struct”具有如下定义的指针数组:

  1. struct task_struct {

  2. struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts];

  3. };

下图显示了相关结构,也来自于该帖子。


CPU在线时将触发CPU级性能事件。但是对于任务级别的perf事件,只能通过运行任务来触发它。“ perf_cpu_context”的task_ctx包含当前正在运行的任务的perf上下文。

性能事件上下文时间表

性能的一项工作是安排任务的perf_event_context的进出时间。

下图显示了与性能相关的任务计划输入和输出功能。

最后,将调用PMU的add和del回调。让我们以跟踪点为例。add回调是“ perf_trace_add”,而del回调是“ perf_trace_add”。

    int perf_trace_add(struct perf_event *p_event, int flags)

  1. {

  2. struct trace_event_call *tp_event = p_event->tp_event;


  3. if (!(flags & PERF_EF_START))

  4. p_event->hw.state = PERF_HES_STOPPED;


  5. /*

  6. * If TRACE_REG_PERF_ADD returns false; no custom action was performed

  7. * and we need to take the default action of enqueueing our event on

  8. * the right per-cpu hlist.

  9. */

  10. if (!tp_event->class->reg(tp_event, TRACE_REG_PERF_ADD, p_event)) {

  11. struct hlist_head __percpu *pcpu_list;

  12. struct hlist_head *list;


  13. pcpu_list = tp_event->perf_events;

  14. if (WARN_ON_ONCE(!pcpu_list))

  15. return -EINVAL;


  16. list = this_cpu_ptr(pcpu_list);

  17. hlist_add_head_rcu(&p_event->hlist_entry, list);

  18. }


  19. return 0;

  20. }


  21. void perf_trace_del(struct perf_event *p_event, int flags)

  22. {

  23. struct trace_event_call *tp_event = p_event->tp_event;


  24. /*

  25. * If TRACE_REG_PERF_DEL returns false; no custom action was performed

  26. * and we need to take the default action of dequeueing our event from

  27. * the right per-cpu hlist.

  28. */

  29. if (!tp_event->class->reg(tp_event, TRACE_REG_PERF_DEL, p_event))

  30. hlist_del_rcu(&p_event->hlist_entry);

  31. }

“ perf_event”将被添加或删除到“ tp_event-> perf_events”列表中。

perf_event_open流

  1. perf_event_open

  2. ->perf_copy_attr

  3. ->get_unused_fd_flags(fd)

  4. ->perf_event_alloc

  5. ->perf_init_event

  6. ->perf_try_init_event

  7. ->pmu->event_init()

  8. ->find_get_context

  9. ->perf_install_in_context

  10. ->__perf_install_in_context

  11. ->add_event_to_ctx

  12. ->list_add_event

  13. ->perf_group_attach

  14. ->add_event_to_ctx

  15. ->fd_install

perf_event_open将调用'pmu-> event_init'来初始化事件。并将perf_event添加到perf_event_context中。

性能跟踪事件

回顾跟踪点PMU的定义。

  1. static struct pmu perf_tracepoint = {

  2. .task_ctx_nr = perf_sw_context,


  3. .event_init = perf_tp_event_init,

  4. .add = perf_trace_add,

  5. .del = perf_trace_del,

  6. .start = perf_swevent_start,

  7. .stop = perf_swevent_stop,

  8. .read = perf_swevent_read,

  9. };

让我们尝试看一下perf子系统如何监视跟踪点事件。

性能事件初始化

称为“ perf_tp_event_init”。

  1. perf_tp_event_init

  2. ->perf_trace_init

  3. ->perf_trace_event_init

  4. ->perf_trace_event_reg

  5. ->tp_event->class->reg(TRACE_REG_PERF_REGISTER)

'perf_trace_init'将找到指定的跟踪点。

“ perf_trace_event_reg”将分配并初始化“ tp_event_perf_events”列表。并使用TRACE_REG_PERF_REGISTER调用“ tp_event-> class-> reg”。

  1. static int perf_trace_event_reg(struct trace_event_call *tp_event,

  2. struct perf_event *p_event)

  3. {

  4. struct hlist_head __percpu *list;

  5. int ret = -ENOMEM;

  6. int cpu;


  7. p_event->tp_event = tp_event;

  8. if (tp_event->perf_refcount++ > 0)

  9. return 0;


  10. list = alloc_percpu(struct hlist_head);

  11. if (!list)

  12. goto fail;


  13. for_each_possible_cpu(cpu)

  14. INIT_HLIST_HEAD(per_cpu_ptr(list, cpu));


  15. tp_event->perf_events = list;


  16. ...

  17. ret = tp_event->class->reg(tp_event, TRACE_REG_PERF_REGISTER, NULL);

  18. if (ret)

  19. goto fail;


  20. total_ref_count++;

  21. return 0;

  22. ...

  23. }

“ tp_event_> class-> reg”回调为“ trace_event_reg”。

  1. int trace_event_reg(struct trace_event_call *call,

  2. enum trace_reg type, void *data)

  3. {

  4. struct trace_event_file *file = data;


  5. WARN_ON(!(call->flags & TRACE_EVENT_FL_TRACEPOINT));

  6. switch (type) {

  7. ...


  8. #ifdef CONFIG_PERF_EVENTS

  9. case TRACE_REG_PERF_REGISTER:

  10. return tracepoint_probe_register(call->tp,

  11. call->class->perf_probe,

  12. call);

  13. case TRACE_REG_PERF_UNREGISTER:

  14. tracepoint_probe_unregister(call->tp,

  15. call->class->perf_probe,

  16. call);

  17. return 0;

  18. case TRACE_REG_PERF_OPEN:

  19. case TRACE_REG_PERF_CLOSE:

  20. case TRACE_REG_PERF_ADD:

  21. case TRACE_REG_PERF_DEL:

  22. return 0;

  23. #endif

  24. }

  25. return 0;

  26. }

我们可以看到'call-> class-> perf_probe'将被注册到跟踪点。从我的帖子。我们知道这个“ perf_probe”是“ perf_trace _ ## call”。


  1. static notrace void

  2. perf_trace_##call(void *__data, proto)

  3. {

  4. struct trace_event_call *event_call = __data;

  5. struct trace_event_data_offsets_##call __maybe_unused __data_offsets;

  6. struct trace_event_raw_##call *entry;

  7. struct pt_regs *__regs;

  8. u64 __count = 1;

  9. struct task_struct *__task = NULL;

  10. struct hlist_head *head;

    int __entry_size;

  11. int __data_size;

  12. int rctx;

  13. __data_size = trace_event_get_offsets_##call(&__data_offsets, args);

  14. head = this_cpu_ptr(event_call->perf_events);

  15. if (!bpf_prog_array_valid(event_call) &&

  16. __builtin_constant_p(!__task) && !__task &&

  17. hlist_empty(head))

    return;

  18. __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),

  19. sizeof(u64));

  20. __entry_size -= sizeof(u32);

  21. entry = perf_trace_buf_alloc(__entry_size, &__regs, &rctx);

  22. if (!entry)

  23. return;

  24. perf_fetch_caller_regs(__regs);

  25. tstruct

  26. { assign; }

  27. perf_trace_run_bpf_submit(entry, __entry_size, rctx,

  28. event_call, __count, __regs,

  29. head, __task);

  30. }

如果“ event_call-> perf_events”为空,则表示没有任何当前的perf_event添加到该跟踪点。这是'perf_event_open'初始化perf_event时的默认状态。

性能事件添加

在CPU中调度任务时,将调用'pmu-> add',并将'perf_event'链接到'event_call-> perf_events'链接列表。

性能事件

从CPU调度任务后,将调用“ pmu-> del”,并且将从“ event_call-> perf_events”链接列表中删除“ perf_event”。

性能事件触发器

如果'event_call-> perf_events'不为空,则将调用'perf_trace_run_bpf_submit'。如果没有附加eBPF程序,则将调用“ perf_tp_event”。

  1.    void perf_tp_event(u16 event_type, u64 count,

                1. void *record, int entry_size,

  2. struct pt_regs *regs, struct hlist_head *head, int rctx,

  3. struct task_struct *task)

  4. {

  5. struct perf_sample_data data;

  6. struct perf_event *event;


  7. struct perf_raw_record raw = {

  8. .frag = {

  9. .size = entry_size,

  10. .data = record,

  11. },

  12. };


  13. perf_sample_data_init(&data, 0, 0);

  14. data.raw = &raw;


  15. perf_trace_buf_update(record, event_type);


  16. hlist_for_each_entry_rcu(event, head, hlist_entry) {

  17. if (perf_tp_event_match(event, &data, regs))

  18. perf_swevent_event(event, count, &data, regs);

  19. }


  20. ...

  21. perf_swevent_put_recursion_context(rctx);

  22. }

对于“ event_call-> perf_events”列表中的每个“ perf_event”。它调用perf_swevent_event触发性能事件。

  1. static void perf_swevent_event(struct perf_event *event,

  2. u64 nr,struct perf_sample_data *data,

  3. struct pt_regs *regs)

  4. {

  5. struct hw_perf_event *hwc = &event->hw;


  6. local64_add(nr, &event->count);


  7. if (!regs)

  8. return;


  9. if (!is_sampling_event(event))

  10. return;


  11. if ((event->attr.sample_type & PERF_SAMPLE_PERIOD)

  12. && !event->attr.freq) {

  13. data->period = nr;

  14. return perf_swevent_overflow(event, 1, data, regs);

  15. } else

  16. data->period = event->hw.last_period;


  17. if (nr == 1 && hwc->sample_period == 1 &&

  18. !event->attr.freq)

  19. return perf_swevent_overflow(event, 1, data, regs);


  20. if (local64_add_negative(nr, &hwc->period_left))

  21. return;


  22. perf_swevent_overflow(event, 0, data, regs);

  23. }

  24. static void perf_swevent_event(struct perf_event *event,

  25. u64 nr,struct perf_sample_data *data,

  26. struct pt_regs *regs)

  27. {

  28. struct hw_perf_event *hwc = &event->hw;


  29. local64_add(nr, &event->count);


  30. if (!regs)

  31. return;


  32. if (!is_sampling_event(event))

  33. return;


  34. if ((event->attr.sample_type & PERF_SAMPLE_PERIOD)

  35. && !event->attr.freq) {

  36. data->period = nr;

  37. return perf_swevent_overflow(event, 1, data, regs);

  38. } else

  39. data->period = event->hw.last_period;


  40. if (nr == 1 && hwc->sample_period == 1

  41. && !event->attr.freq)

  42. return perf_swevent_overflow(event, 1, data, regs);


  43. if (local64_add_negative(nr, &hwc->period_left))

  44. return;


  45. perf_swevent_overflow(event, 0, data, regs);

  46. }

'perf_swevent_event'添加'event-> count'。如果事件未采样,则仅返回。Tis是性能计数模式。如果perf_event在样本模式下,则需要复制跟踪点数据。以下是呼叫链。

  1. perf_swevent_overflow

  2. ->__perf_event_overflow->event

  3. ->overflow_handler(perf_event_output).

软件性能事件

软件PMU定义如下:

  1. static struct pmu perf_swevent = {

  2. .task_ctx_nr = perf_sw_context,


  3. .capabilities = PERF_PMU_CAP_NO_NMI,


  4. .event_init = perf_swevent_init,

  5. .add = perf_swevent_add,

  6. .del = perf_swevent_del,

  7. .start = perf_swevent_start,

  8. .stop = perf_swevent_stop,

  9. .read = perf_swevent_read,

  10. };

性能事件初始化

“ perf_swevent_init”将被调用。它称为“ swevent_hlist_get”

  1. static int perf_swevent_init(struct perf_event *event)

  2. {

  3. u64 event_id = event->attr.config;


  4. if (event->attr.type != PERF_TYPE_SOFTWARE)

  5. return -ENOENT;


  6. /*

  7. * no branch sampling for software events

  8. */

  9. if (has_branch_stack(event))

  10. return -EOPNOTSUPP;


  11. switch (event_id) {

  12. case PERF_COUNT_SW_CPU_CLOCK:

  13. case PERF_COUNT_SW_TASK_CLOCK:

  14. return -ENOENT;


  15. default:

  16. break;

  17. }


  18. if (event_id >= PERF_COUNT_SW_MAX)

  19. return -ENOENT;


  20. if (!event->parent) {

  21. int err;


  22. err = swevent_hlist_get();

  23. if (err)

  24. return err;


  25. static_key_slow_inc(&perf_swevent_enabled[event_id]);

  26. event->destroy = sw_perf_event_destroy;

  27. }


  28. return 0;

  29. }

这将创建一个percpu'swhash-> swevent_hlist'列表。还要将perf_swevent_enabled [event_id]设置为true。

性能事件添加

'perf_swevent_add'将perf_event添加到percpu哈希列表中。

  1. static int perf_swevent_add(struct perf_event *event, int flags)

  2. {

  3. struct swevent_htable *swhash = this_cpu_ptr(&swevent_htable);

  4. struct hw_perf_event *hwc = &event->hw;

  5. struct hlist_head *head;


  6. if (is_sampling_event(event)) {

  7. hwc->last_period = hwc->sample_period;

  8. perf_swevent_set_period(event);

  9. }


  10. hwc->state = !(flags & PERF_EF_START);


  11. head = find_swevent_head(swhash, event);

  12. if (WARN_ON_ONCE(!head))

  13. return -EINVAL;


  14. hlist_add_head_rcu(&event->hlist_entry, head);

  15. perf_event_update_userpage(event);


  16. return 0;

  17. }

性能事件

'perf_swevent_del'从哈希列表中删除。

  1. static void perf_swevent_del(struct perf_event *event, int flags)

  2. {

  3. hlist_del_rcu(&event->hlist_entry);

  4. }



性能事件触发器

以任务开关为例。

“ perf_sw_event_sched”将被调用。

  1. static inline void perf_event_task_sched_out(struct task_struct *prev,

  2. struct task_struct *next)

  3. {

  4. perf_sw_event_sched(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 0);


  5. if (static_branch_unlikely(&perf_sched_events))

  6. __perf_event_task_sched_out(prev, next);

  7. }

perf_event_task_sched_out-> _perf_sw_event-> do_perf_sw_event调用链之后。

  1. static void do_perf_sw_event(enum perf_type_id type, u32 event_id,

  2. u64 nr,

  3. struct perf_sample_data *data,

  4. struct pt_regs *regs)

  5. {

  6. struct swevent_htable *swhash = this_cpu_ptr(&swevent_htable);

  7. struct perf_event *event;

  8. struct hlist_head *head;


  9. rcu_read_lock();

  10. head = find_swevent_head_rcu(swhash, type, event_id);

  11. if (!head)

  12. goto end;


  13. hlist_for_each_entry_rcu(event, head, hlist_entry) {

  14. if (perf_swevent_match(event, type, event_id, data, regs))

  15. perf_swevent_event(event, nr, data, regs);

  16. }

  17. end:

  18. rcu_read_unlock();

  19. }

如我们所见,它最终会调用“ perf_swevent_event”来触发事件。

硬件性能事件

硬件PMU之一定义如下:

  1. static struct pmu pmu = {

  2. .pmu_enable = x86_pmu_enable,

  3. .pmu_disable = x86_pmu_disable,


  4. .attr_groups = x86_pmu_attr_groups,


  5. .event_init = x86_pmu_event_init,


  6. .event_mapped = x86_pmu_event_mapped,

  7. .event_unmapped = x86_pmu_event_unmapped,


  8. .add = x86_pmu_add,

  9. .del = x86_pmu_del,

  10. .start = x86_pmu_start,

  11. .stop = x86_pmu_stop,

  12. .read = x86_pmu_read,


  13. .start_txn = x86_pmu_start_txn,

  14. .cancel_txn = x86_pmu_cancel_txn,

  15. .commit_txn = x86_pmu_commit_txn,


  16. .event_idx = x86_pmu_event_idx,

  17. .sched_task = x86_pmu_sched_task,

  18. .task_ctx_size = sizeof(struct x86_perf_task_context),

  19. .swap_task_ctx = x86_pmu_swap_task_ctx,

  20. .check_period = x86_pmu_check_period,


  21. .aux_output_match = x86_pmu_aux_output_match,

  22. };

硬件性能事件非常复杂,因为它将与硬件交互。这里不会深入介绍硬件。

性能事件初始化

  1. x86_pmu_event_init

  2. ->__x86_pmu_event_init

  3. ->x86_reserve_hardware

  4. ->x86_pmu.hw_config()

  5. ->validate_event


此处的“ x86_pmu”是基于arch规范的PMU结构。

性能事件添加

x86_pmu_add->收集事件->-> x86_pmu.schedule_events()-> x86_pmu.add

'collect_events'集

  1. cpuc->event_list[n] = leader;

性能事件

x86_pmu_del将删除“ cpuc-> event_list”中的事件。

性能事件触发器

触发硬件事件时,它将触发NMI中断。此处理程序是“ perf_event_nmi_handler”。

  1. static int

  2. perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)

  3. {

  4. u64 start_clock;

  5. u64 finish_clock;

  6. int ret;


  7. /*

  8. * All PMUs/events that share this PMI handler should make sure to

  9. * increment active_events for their events.

  10. */

  11. if (!atomic_read(&active_events))

  12. return NMI_DONE;


  13. start_clock = sched_clock();

  14. ret = x86_pmu.handle_irq(regs);

  15. finish_clock = sched_clock();


  16. perf_sample_event_took(finish_clock - start_clock);


  17. return ret;

  18. }

以Taks'x86_pmu.handle_irq'= x86_pmu_handle_irq为例。

  1. for (idx = 0; idx < x86_pmu.num_counters; idx++) {

  2. if (!test_bit(idx, cpuc->active_mask))

  3. continue;


  4. event = cpuc->events[idx];


  5. val = x86_perf_event_update(event);

  6. if (val & (1ULL << (x86_pmu.cntval_bits - 1)))

  7. continue;


  8. /*

  9. * event overflow

  10. */

  11. handled++;

  12. perf_sample_data_init(&data, 0, event->hw.last_period);


  13. if (!x86_perf_event_set_period(event))

  14. continue;


  15. if (perf_event_overflow(event, &data, regs))

  16. x86_pmu_stop(event, 0);

  17. }


在这里,我们可以看到它对“ cpuc”进行了迭代,以查找触发该中断的事件。

Linux阅码场 专业的Linux技术社区和Linux操作系统学习平台,内容涉及Linux内核,Linux内存管理,Linux进程管理,Linux文件系统和IO,Linux性能调优,Linux设备驱动以及Linux虚拟化和云计算等各方各面.
评论
  • 根据Global Info Research(环洋市场咨询)项目团队最新调研,预计2030年全球无人机电池和电源产值达到2834百万美元,2024-2030年期间年复合增长率CAGR为10.1%。 无人机电池是为无人机提供动力并使其飞行的关键。无人机使用的电池类型因无人机的大小和型号而异。一些常见的无人机电池类型包括锂聚合物(LiPo)电池、锂离子电池和镍氢(NiMH)电池。锂聚合物电池是最常用的无人机电池类型,因为其能量密度高、设计轻巧。这些电池以输出功率大、飞行时间长而著称。不过,它们需要
    GIRtina 2025-01-13 10:49 201浏览
  • 01. 什么是过程能力分析?过程能力研究利用生产过程中初始一批产品的数据,预测制造过程是否能够稳定地生产符合规格的产品。可以把它想象成一种预测。通过历史数据的分析,推断未来是否可以依赖该工艺持续生产高质量产品。客户可能会要求将过程能力研究作为生产件批准程序 (PPAP) 的一部分。这是为了确保制造过程能够持续稳定地生产合格的产品。02. 基本概念在定义制造过程时,目标是确保生产的零件符合上下规格限 (USL 和 LSL)。过程能力衡量制造过程能多大程度上稳定地生产符合规格的产品。核心概念很简单:
    优思学院 2025-01-12 15:43 535浏览
  • PNT、GNSS、GPS均是卫星定位和导航相关领域中的常见缩写词,他们经常会被用到,且在很多情况下会被等同使用或替换使用。我们会把定位导航功能测试叫做PNT性能测试,也会叫做GNSS性能测试。我们会把定位导航终端叫做GNSS模块,也会叫做GPS模块。但是实际上他们之间是有一些重要的区别。伴随着技术发展与越发深入,我们有必要对这三个词汇做以清晰的区分。一、什么是GPS?GPS是Global Positioning System(全球定位系统)的缩写,它是美国建立的全球卫星定位导航系统,是GNSS概
    德思特测试测量 2025-01-13 15:42 506浏览
  • 数字隔离芯片是现代电气工程师在进行电路设计时所必须考虑的一种电子元件,主要用于保护低压控制电路中敏感电子设备的稳定运行与操作人员的人身安全。其不仅能隔离两个或多个高低压回路之间的电气联系,还能防止漏电流、共模噪声与浪涌等干扰信号的传播,有效增强电路间信号传输的抗干扰能力,同时提升电子系统的电磁兼容性与通信稳定性。容耦隔离芯片的典型应用原理图值得一提的是,在电子电路中引入隔离措施会带来传输延迟、功耗增加、成本增加与尺寸增加等问题,而数字隔离芯片的目标就是尽可能消除这些不利影响,同时满足安全法规的要
    华普微HOPERF 2025-01-15 09:48 95浏览
  • 新年伊始,又到了对去年做总结,对今年做展望的时刻 不知道你在2024年初立的Flag都实现了吗? 2025年对自己又有什么新的期待呢? 2024年注定是不平凡的一年, 一年里我测评了50余块开发板, 写出了很多科普文章, 从一个小小的工作室成长为科工公司。 展望2025年, 中国香河英茂科工, 会继续深耕于,具身机器人、飞行器、物联网等方面的研发, 我觉得,要向未来学习未来, 未来是什么? 是掌握在孩子们生活中的发现,和精历, 把最好的技术带给孩子,
    丙丁先生 2025-01-11 11:35 466浏览
  • 食物浪费已成为全球亟待解决的严峻挑战,并对环境和经济造成了重大影响。最新统计数据显示,全球高达三分之一的粮食在生产过程中损失或被无谓浪费,这不仅导致了资源消耗,还加剧了温室气体排放,并带来了巨大经济损失。全球领先的光学解决方案供应商艾迈斯欧司朗(SIX:AMS)近日宣布,艾迈斯欧司朗基于AS7341多光谱传感器开发的创新应用来解决食物浪费这一全球性难题。其多光谱传感解决方案为农业与食品行业带来深远变革,该技术通过精确判定最佳收获时机,提升质量控制水平,并在整个供应链中有效减少浪费。 在2024
    艾迈斯欧司朗 2025-01-14 18:45 71浏览
  • 随着数字化的不断推进,LED显示屏行业对4K、8K等超高清画质的需求日益提升。与此同时,Mini及Micro LED技术的日益成熟,推动了间距小于1.2 Pitch的Mini、Micro LED显示屏的快速发展。这类显示屏不仅画质卓越,而且尺寸适中,通常在110至1000英寸之间,非常适合应用于电影院、监控中心、大型会议、以及电影拍摄等多种室内场景。鉴于室内LED显示屏与用户距离较近,因此对于噪音控制、体积小型化、冗余备份能力及电气安全性的要求尤为严格。为满足这一市场需求,开关电源技术推出了专为
    晶台光耦 2025-01-13 10:42 516浏览
  •   在信号处理过程中,由于信号的时域截断会导致频谱扩展泄露现象。那么导致频谱泄露发生的根本原因是什么?又该采取什么样的改善方法。本文以ADC性能指标的测试场景为例,探讨了对ADC的输出结果进行非周期截断所带来的影响及问题总结。 两个点   为了更好的分析或处理信号,实际应用时需要从频域而非时域的角度观察原信号。但物理意义上只能直接获取信号的时域信息,为了得到信号的频域信息需要利用傅里叶变换这个工具计算出原信号的频谱函数。但对于计算机来说实现这种计算需要面对两个问题: 1.
    TIAN301 2025-01-14 14:15 118浏览
  • ARMv8-A是ARM公司为满足新需求而重新设计的一个架构,是近20年来ARM架构变动最大的一次。以下是对ARMv8-A的详细介绍: 1. 背景介绍    ARM公司最初并未涉足PC市场,其产品主要针对功耗敏感的移动设备。     随着技术的发展和市场需求的变化,ARM开始扩展到企业设备、服务器等领域,这要求其架构能够支持更大的内存和更复杂的计算任务。 2. 架构特点    ARMv8-A引入了Execution State(执行状
    丙丁先生 2025-01-12 10:30 478浏览
  • 流量传感器是实现对燃气、废气、生活用水、污水、冷却液、石油等各种流体流量精准计量的关键手段。但随着工业自动化、数字化、智能化与低碳化进程的不断加速,采用传统机械式检测方式的流量传感器已不能满足当代流体计量行业对于测量精度、测量范围、使用寿命与维护成本等方面的精细需求。流量传感器的应用场景(部分)超声波流量传感器,是一种利用超声波技术测量流体流量的新型传感器,其主要通过发射超声波信号并接收反射回来的信号,根据超声波在流体中传播的时间、幅度或相位变化等参数,间接计算流体的流量,具有非侵入式测量、高精
    华普微HOPERF 2025-01-13 14:18 500浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦